Leaked source code of windows server 2003
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.
 
 
 
 
 
 

347 lines
8.6 KiB

/****************************** Module Header ******************************\
* Module Name: pipe.c
*
* Copyright (c) 1991, Microsoft Corporation
*
* This module implements:
* 1. a version of CreatePipe that allows control over the file
* flags. e.g. FILE_FLAG_OVERLAPPED
* 2. Timed-out pipe read and write
*
* History:
* 06-29-92 Davidc Created.
* 05-17-94 DaveTh Added ReadPipe, WritePipe.
\***************************************************************************/
#include <nt.h>
#include <ntrtl.h>
#include <windef.h>
#include <nturtl.h>
#include <winbase.h>
#include "rcmdsrv.h"
ULONG PipeSerialNumber = 0;
#define PIPE_FORMAT_STRING "\\\\.\\pipe\\rshsrv\\%08x.%08x"
/////////////////////////////////////////////////////////////////////////////
//
// RcCreatePipe
//
// Creates a uni-directional pipe with the specified security attributes,
// size and timeout. The handles are opened with the specified file-flags
// so FILE_FLAG_OVERLAPPED etc. can be specified.
//
// Returns handles to both end of pipe in passed parameters.
//
// Returns TRUE on success, FALSE on failure. (GetLastError() for details)
//
/////////////////////////////////////////////////////////////////////////////
BOOL
RcCreatePipe(
LPHANDLE ReadHandle,
LPHANDLE WriteHandle,
LPSECURITY_ATTRIBUTES SecurityAttributes,
DWORD Size,
DWORD Timeout,
DWORD ReadHandleFlags,
DWORD WriteHandleFlags
)
{
CHAR PipeName[MAX_PATH];
//
// Make up a random pipe name
//
sprintf(PipeName, PIPE_FORMAT_STRING, GetCurrentProcessId(), PipeSerialNumber++);
//
// Create the pipe
//
*ReadHandle = CreateNamedPipeA(
PipeName,
PIPE_ACCESS_INBOUND | ReadHandleFlags,
PIPE_TYPE_BYTE | PIPE_WAIT,
1, // Number of pipes
Size, // Out buffer size
Size, // In buffer size
Timeout, // Timeout in ms
SecurityAttributes
);
if (*ReadHandle == NULL) {
RcDbgPrint("RcCreatePipe: failed to created pipe <%s>, error = %d\n", PipeName, GetLastError());
return(FALSE);
}
//
// Open the client end of the pipe
//
*WriteHandle = CreateFileA(
PipeName,
GENERIC_WRITE,
0, // No sharing
SecurityAttributes,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | WriteHandleFlags,
NULL // Template file
);
if (*WriteHandle == INVALID_HANDLE_VALUE ) {
RcDbgPrint("Failed to open client end of pipe <%s>, error = %d\n", PipeName, GetLastError());
RcCloseHandle(*ReadHandle, "async pipe (server(read) side)");
return(FALSE);
}
//
// Everything succeeded
//
return(TRUE);
}
/***************************************************************************\
* FUNCTION: ReadPipe
*
* PURPOSE: Implements a timed-out (ms) read on a pipe.
*
* RETURNS: ERROR_SUCCESS on success
* WAIT_TIMEOUT if timed out before completing read
* or respective error code on other failures
*
* HISTORY:
*
* 05-17-94 DaveTh Created from DavidC read pipe.
*
\***************************************************************************/
DWORD
ReadPipe(
HANDLE PipeHandle,
LPVOID lpBuffer,
DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead,
DWORD Timeout
)
{
DWORD Result;
OVERLAPPED Overlapped;
HANDLE EventHandle;
DWORD Error;
//
// Create an event for the overlapped operation
//
EventHandle = CreateEvent(
NULL, // no security
TRUE, // Manual reset
FALSE, // Initial state
NULL // Name
);
if (EventHandle == NULL) {
RcDbgPrint("Internal error = %d\n", GetLastError());
return(GetLastError());
}
Overlapped.hEvent = EventHandle;
Result = ReadFile(
PipeHandle,
lpBuffer,
nNumberOfBytesToRead,
lpNumberOfBytesRead,
&Overlapped
);
if (Result) {
//
// Success without waiting - it's too easy !
//
CloseHandle(EventHandle);
} else {
//
// Read failed, if it's overlapped io, go wait for it
//
Error = GetLastError();
if (Error != ERROR_IO_PENDING) {
RcDbgPrint("ReadPipe: ReadFile failed, error = %d\n", Error);
CloseHandle(EventHandle);
return(Error);
}
//
// Wait for the I/O to complete
//
Result = WaitForSingleObject(EventHandle, Timeout);
if (Result != WAIT_OBJECT_0) {
if (Result == WAIT_TIMEOUT) {
return(Result);
} else {
RcDbgPrint("ReadPipe: event wait failed, result = %d, last error = %d\n", Result, GetLastError());
}
CloseHandle(EventHandle);
}
//
// Go get the I/O result
//
Result = GetOverlappedResult( PipeHandle,
&Overlapped,
lpNumberOfBytesRead,
FALSE
);
//
// We're finished with the event handle
//
CloseHandle(EventHandle);
//
// Check result of GetOverlappedResult
//
if (!Result) {
RcDbgPrint("ReadPipe: GetOverlappedResult failed, error = %d\n", GetLastError());
return(GetLastError());
}
}
return(ERROR_SUCCESS);
}
/***************************************************************************\
* FUNCTION: WritePipe
*
* PURPOSE: Implements a timed-out (ms) write on a pipe.
*
* RETURNS: ERROR_SUCCESS on success
* WAIT_TIMEOUT if timed out before completing write
* or respective error code on other failures
*
* HISTORY:
*
* 05-22-94 DaveTh Created.
*
\***************************************************************************/
DWORD
WritePipe(
HANDLE PipeHandle,
LPVOID lpBuffer,
DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten,
DWORD Timeout
)
{
DWORD Result;
OVERLAPPED Overlapped;
HANDLE EventHandle;
DWORD Error;
//
// Create an event for the overlapped operation
//
EventHandle = CreateEvent(
NULL, // no security
TRUE, // Manual reset
FALSE, // Initial state
NULL // Name
);
if (EventHandle == NULL) {
RcDbgPrint("Internal error = %d\n", GetLastError());
return(GetLastError());
}
Overlapped.hEvent = EventHandle;
Result = WriteFile(
PipeHandle,
lpBuffer,
nNumberOfBytesToWrite,
lpNumberOfBytesWritten,
&Overlapped
);
if (Result) {
//
// Success without waiting - it's too easy !
//
CloseHandle(EventHandle);
} else {
//
// Write failed, if it's overlapped io, go wait for it
//
Error = GetLastError();
if (Error != ERROR_IO_PENDING) {
RcDbgPrint("WritePipe: WriteFile failed, error = %d\n", Error);
CloseHandle(EventHandle);
return(Error);
}
//
// Wait for the I/O to complete
//
Result = WaitForSingleObject(EventHandle, Timeout);
if (Result != WAIT_OBJECT_0) {
if (Result == WAIT_TIMEOUT) {
return(Result);
} else {
RcDbgPrint("Write: event wait failed, result = %d, last error = %d\n", Result, GetLastError());
}
CloseHandle(EventHandle);
}
//
// Go get the I/O result
//
Result = GetOverlappedResult( PipeHandle,
&Overlapped,
lpNumberOfBytesWritten,
FALSE
);
//
// We're finished with the event handle
//
CloseHandle(EventHandle);
//
// Check result of GetOverlappedResult
//
if (!Result) {
RcDbgPrint("WritePipe: GetOverlappedResult failed, error = %d\n", GetLastError());
return(GetLastError());
}
}
return(ERROR_SUCCESS);
}