/*++
Copyright 1996 - 1997 Microsoft Corporation
Module Name:
client.c
Abstract:
This sample illustrates a simple client side of the DuplicateTokenEx()
server sample.
This client functions correctly on the following platforms:
Windows NT 3.5
Windows NT 3.51
Windows NT 4.0
Windows 95
Author:
Scott Field (sfield) 02-Apr-96
--*/
#include <windows.h>
#include <stdio.h>
DWORD
WINAPI
ReadFunc(
LPVOID lpParam
);
DWORD
WINAPI
WriteFunc(
LPVOID lpParam
);
void
DisplayWinError(
LPSTR szAPI, // pointer to Ansi function name
DWORD dwError // DWORD WinError
);
#define RTN_OK 0
#define RTN_USAGE 1
#define RTN_ERROR 13
int
__cdecl
main(
int argc,
char *argv[]
)
{
HANDLE hFileRead;
HANDLE hFileWrite;
HANDLE hThread;
DWORD dwThreadId;
CHAR PipeIn[255];
CHAR PipeOut[255];
if(argc == 1) {
printf("Usage: %s <\\\\server\n", argv[0]);
printf(" %s \\\\WINBASE (remote server is \\\\winbase)\n", argv[0]);
printf(" %s \\\\. (local server)\n", argv[0]);
return RTN_USAGE;
}
//
// build Pipe names
//
wsprintf(PipeIn, "%s\\pipe\\rcmd_out", argv[1]);
wsprintf(PipeOut, "%s\\pipe\\rcmd_in", argv[1]);
//
// wait for the outbound (inbound on server-side) pipe to be available
//
WaitNamedPipe(PipeOut, NMPWAIT_WAIT_FOREVER);
hFileWrite = CreateFile(
PipeOut,
GENERIC_WRITE,
0, // exclusive open
NULL,
OPEN_EXISTING,
SECURITY_SQOS_PRESENT | SECURITY_IMPERSONATION, // server can impersonate
NULL
);
if(hFileWrite == INVALID_HANDLE_VALUE) {
DisplayWinError("CreateFile", GetLastError());
return RTN_ERROR;
}
//
// wait for the inbound (outbound on server-side) pipe to be available
// we time-out in 5 seconds because the server should be ready for us
// right-away
//
WaitNamedPipe(PipeIn, 5 * 1000);
hFileRead = CreateFile(
PipeIn,
GENERIC_READ,
0, // exclusive open
NULL,
OPEN_EXISTING,
0,
NULL
);
if(hFileRead == INVALID_HANDLE_VALUE) {
DisplayWinError("CreateFile", GetLastError());
return RTN_ERROR;
}
//
// start a thread to handle stdin redirection to the pipe
//
hThread = CreateThread(
NULL,
0,
WriteFunc,
(LPVOID)hFileWrite, // parm
0,
&dwThreadId
);
if(hThread == NULL) {
DisplayWinError("CreateThread", GetLastError());
return RTN_ERROR;
}
//
// handle stdout redirection
//
ReadFunc((LPVOID)hFileRead);
//
// if the read returned, kill the write, cleanup, and then exit
//
TerminateThread(hThread, 0xFFFFFFFF);
CloseHandle(hThread);
CloseHandle(hFileRead);
CloseHandle(hFileWrite);
return RTN_OK;
}
DWORD
WINAPI
ReadFunc(
LPVOID lpParam
)
{
#define BUFFER_SIZE 4096
HANDLE hFile = (HANDLE)lpParam;
BYTE lpBuffer[BUFFER_SIZE];
DWORD dwBytesRead;
DWORD dwBytesWritten;
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD dwLastError;
while (1) {
if(!ReadFile(
hFile,
lpBuffer,
BUFFER_SIZE,
&dwBytesRead,
NULL
)) {
dwLastError = GetLastError();
if(dwLastError == ERROR_NO_DATA) continue;
if(dwLastError != ERROR_MORE_DATA) break;
}
if(!WriteFile(
hStdOut,
lpBuffer,
dwBytesRead,
&dwBytesWritten,
NULL
)) break;
}
return GetLastError();
}
DWORD
WINAPI
WriteFunc(
LPVOID lpParam
)
{
HANDLE hPipe = (HANDLE)lpParam;
BYTE lpBuffer[ 1 ]; // change this later
DWORD dwBytesRead;
DWORD dwBytesWritten;
HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
while (1) {
//
// TODO rework this loop to be line-based.
// this would entail doing the console buffering outselves.
//
if(!ReadFile(
hStdIn,
lpBuffer,
1,
&dwBytesRead,
NULL
)) break;
if(!WriteFile(
hPipe,
lpBuffer,
dwBytesRead,
&dwBytesWritten,
NULL
)) break;
}
return GetLastError();
}
void
DisplayWinError(
LPSTR szAPI, // pointer to Ansi function name
DWORD dwError // DWORD WinError
)
{
LPSTR MessageBuffer;
DWORD dwBufferLength;
//
// TODO get this fprintf out of here!
//
fprintf(stderr,"%s error!\n", szAPI);
if(dwBufferLength=FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
dwError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR) &MessageBuffer,
0,
NULL
))
{
DWORD dwBytesWritten; // unused
//
// Output message string on stderr
//
WriteFile(
GetStdHandle(STD_ERROR_HANDLE),
MessageBuffer,
dwBufferLength,
&dwBytesWritten,
NULL
);
//
// free the buffer allocated by the system
//
LocalFree(MessageBuffer);
}
}