mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
483 lines
9.1 KiB
483 lines
9.1 KiB
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
pipesrv.c
|
|
|
|
Abstract:
|
|
|
|
Named pipe server. This program creates a named pipe performs
|
|
I/O on the pipe based on command line arguments.
|
|
|
|
The pipe used by this test is "\\Device\NamedPipe\Pipetest".
|
|
|
|
Author:
|
|
|
|
Manny Weiser (Oct 1, 1990)
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#define TEST_PIPE "\\Device\\NamedPipe\\TestPipe"
|
|
|
|
#include "pipesrv.h"
|
|
|
|
//
|
|
// Global variables
|
|
//
|
|
|
|
HANDLE NamedPipeHandle;
|
|
UCHAR Buffer[64*1024 - 1];
|
|
PSZ SourceString = "Named pipe test";
|
|
PVOID Heap;
|
|
|
|
//
|
|
// Local functions
|
|
//
|
|
|
|
NTSTATUS
|
|
Initialize(
|
|
IN PSTRING PipeName,
|
|
OUT PHANDLE handle
|
|
);
|
|
|
|
NTSTATUS
|
|
ListenPipe(
|
|
IN HANDLE Handle
|
|
);
|
|
|
|
NTSTATUS
|
|
PerformIO(
|
|
IN HANDLE Handle,
|
|
IN SHORT Argc,
|
|
IN PSZ Argv[]
|
|
);
|
|
|
|
NTSTATUS
|
|
WriteReadLoop(
|
|
IN HANDLE Handle,
|
|
IN USHORT Size
|
|
);
|
|
|
|
NTSTATUS
|
|
PerformCommand (
|
|
IN HANDLE Handle,
|
|
IN PSZ Command
|
|
);
|
|
|
|
VOID
|
|
ShutDown(
|
|
IN HANDLE Handle
|
|
);
|
|
|
|
|
|
NTSTATUS
|
|
main (
|
|
IN SHORT argc,
|
|
IN PSZ argv[],
|
|
IN PSZ envp[]
|
|
)
|
|
{
|
|
HANDLE handle;
|
|
STRING pipeName;
|
|
NTSTATUS status;
|
|
|
|
argc, argv, envp; // Shut up the compiler
|
|
|
|
// DbgBreakPoint();
|
|
|
|
pipeName.Buffer = TEST_PIPE;
|
|
pipeName.Length = pipeName.MaximumLength = (USHORT)sizeof( TEST_PIPE ) -1;
|
|
|
|
status = Initialize (&pipeName, &handle);
|
|
if (!NT_SUCCESS(status)) {
|
|
return 1;
|
|
}
|
|
|
|
status = ListenPipe (handle);
|
|
if (!NT_SUCCESS(status)) {
|
|
ShutDown(handle);
|
|
return 1;
|
|
}
|
|
|
|
status = PerformIO (handle, argc, argv);
|
|
if (!NT_SUCCESS(status)) {
|
|
ShutDown(handle);
|
|
return 1;
|
|
}
|
|
|
|
ShutDown(handle);
|
|
return 0;
|
|
} // main
|
|
|
|
|
|
NTSTATUS
|
|
Initialize(
|
|
IN PSTRING PipeName,
|
|
OUT PHANDLE Handle
|
|
)
|
|
|
|
{
|
|
OBJECT_ATTRIBUTES objectAttributes;
|
|
IO_STATUS_BLOCK ioStatusBlock;
|
|
NTSTATUS status;
|
|
LARGE_INTEGER Timeout;
|
|
PUCHAR ptr;
|
|
USHORT size, bytesRemaining;
|
|
UNICODE_STRING unicodePipeName;
|
|
|
|
printf ("PIPESRV: Creating Named Pipe\n");
|
|
|
|
//
|
|
// Create the pipe
|
|
//
|
|
|
|
status = RtlAnsiStringToUnicodeString(
|
|
&unicodePipeName,
|
|
PipeName,
|
|
TRUE
|
|
);
|
|
ASSERT( NT_SUCCESS(status) );
|
|
|
|
InitializeObjectAttributes(
|
|
&objectAttributes,
|
|
&unicodePipeName,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
//
|
|
// Set the default timeout to 60 seconds, and initalize the attributes
|
|
//
|
|
|
|
|
|
Timeout.QuadPart = Int32x32To64( -10 * 1000 * 1000, 60 );
|
|
|
|
status = NtCreateNamedPipeFile (
|
|
Handle,
|
|
GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
|
|
&objectAttributes,
|
|
&ioStatusBlock,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE, // Share access
|
|
FILE_CREATE,
|
|
0, // Create Options
|
|
FILE_PIPE_MESSAGE_TYPE,
|
|
FILE_PIPE_MESSAGE_MODE,
|
|
FILE_PIPE_QUEUE_OPERATION, // Blocking
|
|
1, // Max instances
|
|
1024, // Inbound quota
|
|
1024, // Outbound quota
|
|
(PLARGE_INTEGER)&Timeout // Default timeout
|
|
);
|
|
|
|
RtlFreeUnicodeString( &unicodePipeName );
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
printf ("PIPESRV: Failed to open named pipe %Z, err=%lx\n",
|
|
PipeName, status);
|
|
} else {
|
|
printf ("PIPESRV: Successfully created %Z\n", PipeName);
|
|
}
|
|
|
|
//
|
|
// Use the process heap for memory allocations.
|
|
//
|
|
|
|
Heap = RtlProcessHeap();
|
|
|
|
//
|
|
// Initialize the send buffer
|
|
//
|
|
|
|
ptr = Buffer;
|
|
bytesRemaining = sizeof(Buffer);
|
|
size = (USHORT)strlen(SourceString);
|
|
|
|
while (bytesRemaining > 0) {
|
|
if (bytesRemaining >= size) {
|
|
RtlMoveMemory(ptr, SourceString, size);
|
|
ptr += size;
|
|
bytesRemaining -= size;
|
|
} else {
|
|
RtlMoveMemory(ptr, SourceString, bytesRemaining);
|
|
bytesRemaining = 0;
|
|
}
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
ListenPipe(
|
|
IN HANDLE Handle
|
|
)
|
|
{
|
|
IO_STATUS_BLOCK ioStatusBlock;
|
|
NTSTATUS status;
|
|
|
|
printf ("PIPESRV: Issuing listen on pipe\n");
|
|
|
|
status = NtFsControlFile (
|
|
Handle,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&ioStatusBlock,
|
|
FSCTL_PIPE_LISTEN,
|
|
NULL,
|
|
0,
|
|
NULL,
|
|
0
|
|
);
|
|
|
|
if (status == STATUS_PENDING) {
|
|
|
|
status = NtWaitForSingleObject( Handle, TRUE, NULL );
|
|
if (NT_SUCCESS(status)) {
|
|
status == ioStatusBlock.Status;
|
|
}
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
printf ("PIPESRV: Listen pipe failed, err=%lx\n", status);
|
|
} else {
|
|
printf ("PIPESRV: Listen succeeded, pipe is ready\n");
|
|
}
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
PerformIO(
|
|
IN HANDLE Handle,
|
|
IN SHORT Argc,
|
|
IN PSZ Argv[]
|
|
)
|
|
{
|
|
CSHORT i;
|
|
NTSTATUS status;
|
|
|
|
if (Argc == 1) {
|
|
|
|
//
|
|
// No command line arguments. Loop writing then reading 2048
|
|
// byte blocks of data.
|
|
//
|
|
|
|
WriteReadLoop( Handle, 2048 );
|
|
|
|
} else {
|
|
|
|
//
|
|
// Loop through, parsing and performing actions described in
|
|
// command line arguments.
|
|
//
|
|
|
|
for (i = 1; i < Argc; i ++) {
|
|
status = PerformCommand ( Handle, Argv[i] );
|
|
if (!NT_SUCCESS(status)) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS
|
|
PerformCommand (
|
|
IN HANDLE Handle,
|
|
IN PSZ Command
|
|
)
|
|
|
|
{
|
|
IO_STATUS_BLOCK ioStatusBlock;
|
|
ULONG length;
|
|
ULONG actualRead;
|
|
NTSTATUS status;
|
|
|
|
switch (*Command) {
|
|
|
|
case 'r':
|
|
|
|
length = atoi(Command+1);
|
|
|
|
status = NtReadFile(
|
|
Handle,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&ioStatusBlock,
|
|
Buffer,
|
|
length,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
if (status == STATUS_PENDING) {
|
|
status = NtWaitForSingleObject(Handle, TRUE, NULL);
|
|
if (NT_SUCCESS(status)) {
|
|
status = ioStatusBlock.Status;
|
|
}
|
|
}
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
actualRead = ioStatusBlock.Information;
|
|
printf ("PIPESRV: Successfully read %d bytes\n", actualRead);
|
|
} else {
|
|
printf ("PIPESRV: PerformIO: NtReadFail err=%lx\n", status);
|
|
}
|
|
|
|
break;
|
|
|
|
case 'w':
|
|
|
|
length = atoi(Command+1);
|
|
|
|
status = NtWriteFile(
|
|
Handle,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&ioStatusBlock,
|
|
Buffer,
|
|
length,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
if (status == STATUS_PENDING) {
|
|
status = NtWaitForSingleObject(Handle, TRUE, NULL);
|
|
if (NT_SUCCESS(status)) {
|
|
status = ioStatusBlock.Status;
|
|
}
|
|
}
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
actualRead = ioStatusBlock.Information;
|
|
printf ("PIPESRV: Successfully wrote %d bytes\n", actualRead);
|
|
} else {
|
|
printf ("PIPESRV: PerformIO: NtReadFail err=%lx\n", status);
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
printf ("PIPESRV: Unknown command ""%s""\n", Command);
|
|
break;
|
|
|
|
} // switch
|
|
|
|
return status;
|
|
} // PerformCommand()
|
|
|
|
|
|
NTSTATUS
|
|
WriteReadLoop(
|
|
IN HANDLE Handle,
|
|
IN USHORT Size
|
|
)
|
|
|
|
{
|
|
NTSTATUS status;
|
|
IO_STATUS_BLOCK ioStatusBlock;
|
|
ULONG actualRead;
|
|
|
|
//
|
|
// Loop forever writing then reading the named pipe
|
|
//
|
|
|
|
while (TRUE) {
|
|
|
|
//
|
|
// Write the output buffer
|
|
//
|
|
|
|
status = NtWriteFile(
|
|
Handle,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&ioStatusBlock,
|
|
Buffer,
|
|
Size,
|
|
NULL,
|
|
NULL);
|
|
|
|
//
|
|
// Wait for write completion.
|
|
//
|
|
|
|
if (status == STATUS_PENDING) {
|
|
status = NtWaitForSingleObject(Handle, TRUE, NULL);
|
|
if (NT_SUCCESS(status)) {
|
|
status = ioStatusBlock.Status;
|
|
}
|
|
|
|
}
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
printf ("PIPESRV: Successfully wrote %d bytes\n", 2048);
|
|
} else {
|
|
printf ("PIPESRV: PerformIO: NtWriteFail err=%lx\n", status);
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Now read
|
|
//
|
|
|
|
status = NtReadFile(
|
|
Handle,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&ioStatusBlock,
|
|
Buffer,
|
|
Size,
|
|
NULL,
|
|
NULL);
|
|
|
|
//
|
|
// Wait for read completion
|
|
//
|
|
|
|
if (status == STATUS_PENDING) {
|
|
status = NtWaitForSingleObject(Handle, TRUE, NULL);
|
|
if (NT_SUCCESS(status)) {
|
|
status = ioStatusBlock.Status;
|
|
}
|
|
}
|
|
|
|
if (NT_SUCCESS(status)) {
|
|
actualRead = ioStatusBlock.Information;
|
|
printf ("PIPESRV: Successfully read %d bytes\n", actualRead);
|
|
} else {
|
|
printf ("PIPESRV: PerformIO: NtReadFail err=%lx\n", status);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
VOID
|
|
ShutDown(
|
|
IN HANDLE Handle
|
|
)
|
|
|
|
{
|
|
NtClose (Handle);
|
|
// NtClose (NamedPipeHandle);
|
|
printf ("PIPESRV: Exiting\n");
|
|
|
|
return;
|
|
}
|