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.
 
 
 
 
 
 

283 lines
7.4 KiB

/*++
Copyright (c) 2001 Microsoft Corporation
Module Name:
pipedata.hxx
Abstract:
Encapsulation of message passing over named pipes.
IPM_MESSAGEs are delivered messages from the other side of the pipe
IPM_MESSAGE_ACCEPTORs is the interface clients of this API must implement
IPM_MESSAGE_PIPE is the creation, deletion, and write interface for this API
Threading:
It is valid to call the API on any thread
Callbacks can occur on an NT thread, or on the thread that was calling into the API.
Author:
Jeffrey Wall (jeffwall) 9/12/2001
Revision History:
--*/
#ifndef _PIPEDATA_HXX_
#define _PIPEDATA_HXX_
//
// When starting in backward compatibility mode, we use a well known pipe name
//
#define WEB_ADMIN_SERVICE_INETINFO_PIPENAME L"\\\\.\\pipe\\iisipm14acf167-60fe-4c1d-8563-f209abaa8f4b"
enum IPM_WP_SHUTDOWN_MSG;
//
// IPM opcodes
//
// **********************************
// These must be kept in synch with the METADATA for the opcodes below.
// **********************************
//
enum IPM_OPCODE
{
IPM_OP_MINIMUM = 0,
IPM_OP_PING,
IPM_OP_PING_REPLY,
IPM_OP_WORKER_REQUESTS_SHUTDOWN,
IPM_OP_SHUTDOWN,
IPM_OP_REQUEST_COUNTERS,
IPM_OP_SEND_COUNTERS,
IPM_OP_PERIODIC_PROCESS_RESTART_PERIOD_IN_MINUTES,
IPM_OP_PERIODIC_PROCESS_RESTART_MEMORY_USAGE_IN_KB,
IPM_OP_PERIODIC_PROCESS_RESTART_SCHEDULE,
IPM_OP_GETPID,
IPM_OP_HRESULT,
IPM_OP_MAXIMUM
};
struct IPM_OPCODE_METADATA
{
size_t sizeMaximumAndRequiredSize;
BOOL fServerSideExpectsThisMessage;
};
IPM_OPCODE_METADATA IPM_OP_DATA_SIZE [] = {
{ 0, FALSE }, //IPM_OP_MINIMUM
{ 0, FALSE }, //IPM_OP_PING
{ 0, TRUE }, //IPM_OP_PING_REPLY
{ sizeof(IPM_WP_SHUTDOWN_MSG), TRUE }, //IPM_OP_WORKER_REQUESTS_SHUTDOWN
{ sizeof(BOOL), FALSE }, // IPM_OP_SHUTDOWN
{ 0, FALSE }, //IPM_OP_REQUEST_COUNTERS
{ MAXLONG, TRUE }, //IPM_OP_SEND_COUNTERS
{ sizeof(DWORD), FALSE }, //IPM_OP_PERIODIC_PROCESS_RESTART_PERIOD_IN_MINUTES
{ 2 * sizeof(DWORD), FALSE }, //IPM_OP_PERIODIC_PROCESS_RESTART_MEMORY_USAGE_IN_KB
{ MAXLONG, FALSE }, //IPM_OP_PERIODIC_PROCESS_RESTART_SCHEDULE
{ sizeof(DWORD), TRUE }, //IPM_OP_GETPID
{ sizeof(HRESULT), TRUE }, //IPM_OP_HRESULT
{ 0, FALSE } //IPM_OP_MAXIMUM
};
//
// Data sent on a IPM_OP_WORKER_REQUESTS_SHUTDOWN message, to give the
// reason for the message.
//
enum IPM_WP_SHUTDOWN_MSG
{
IPM_WP_MINIMUM = 0,
IPM_WP_RESTART_COUNT_REACHED,
IPM_WP_IDLE_TIME_REACHED,
IPM_WP_RESTART_SCHEDULED_TIME_REACHED,
IPM_WP_RESTART_ELAPSED_TIME_REACHED,
IPM_WP_RESTART_VIRTUAL_MEMORY_LIMIT_REACHED,
IPM_WP_RESTART_ISAPI_REQUESTED_RECYCLE,
IPM_WP_RESTART_PRIVATE_BYTES_LIMIT_REACHED,
IPM_WP_MAXIMUM
};
//
// forward declarations and export directives
//
class dllexp IPM_MESSAGE_PIPE;
class IPM_MESSAGE_IMP;
//
// There is one implementation of this interface (IPM_MESSAGE_IMP)
//
// The implementation is not exposed here because it has many more
// public methods (ex: SetData) that are not needed by MESSAGE_ACCEPTORs
// and serve only to confuse the data abstraction being exposed.
//
class IPM_MESSAGE
{
public:
//
// returns the IPM_OPCODE associated with this message
//
virtual IPM_OPCODE GetOpcode() const = 0;
//
// returns the data length of the message
//
virtual DWORD GetDataLen() const = 0;
//
// returns a pointer to the data of the message
//
virtual const BYTE * GetData() const = 0;
}; // IPM_MESSAGE
//
// Users of this pipe mechanism are required to implement this interface
// to receive pipe event callbacks.
//
// These callbacks will occur on NT Thread Pool threads, or sometimes
// on the same thread that was used in a call to any MESSAGE_PIPE
// instance
//
class IPM_MESSAGE_ACCEPTOR
{
public:
//
// Called when an IPM_MESSAGE is received on the pipe
//
virtual VOID AcceptMessage(IN CONST IPM_MESSAGE * pMessage) = 0;
//
// Called when the pipe is ready to read and write data
//
virtual VOID PipeConnected() = 0;
//
// Called when the pipe is no longer connected
//
virtual VOID PipeDisconnected(IN HRESULT Error) = 0;
//
// Called when an invalid message has arrived from the other side of the pipe
//
virtual VOID PipeMessageInvalid() = 0;
}; // IPM_MESSAGE_ACCEPTOR
//
// interface to pipe mechanism.
//
class IPM_MESSAGE_PIPE
{
private:
IPM_MESSAGE_PIPE();
~IPM_MESSAGE_PIPE();
public:
// Create returns a IPM_MESSAGE_PIPE for use
static
HRESULT
CreateIpmMessagePipe(IPM_MESSAGE_ACCEPTOR * pAcceptor, // callback class
LPCWSTR pszPipeName, // name of pipe
BOOL fServerSide, // TRUE for CreateNamedPipe, FALSE for CreateFile
PSECURITY_ATTRIBUTES pSa, // security attributes to apply to pipe
IPM_MESSAGE_PIPE ** ppPipe); // outgoing pipe
// Destroy disconnects the IPM_MESSAGE_PIPE, blocks until all work is finished, and deletes the IPM_MESSAGE_PIPE
VOID
DestroyIpmMessagePipe();
// WriteMessage places a message on the pipe
HRESULT
WriteMessage(IPM_OPCODE opcode,
DWORD dwDataLen,
LPVOID pbData);
//
// The following functions are not for public consumption.
// If you abuse them, I'll take them away.
//
BOOL
IsValid();
VOID IpmMessageCreated(IPM_MESSAGE_IMP *);
VOID IpmMessageDeleted(IPM_MESSAGE_IMP *);
// Register wait callback function
static
VOID
CALLBACK
MessagePipeCompletion(LPVOID pvoid,
BOOLEAN TimerOrWaitFired);
private:
DWORD m_dwSignature;
// handle to NT pipe
HANDLE m_hPipe;
// callback pointer
IPM_MESSAGE_ACCEPTOR * m_pAcceptor;
// TRUE if CreateNamedPipe was called, otherwise FALSE;
BOOL m_fServerSide;
// count of # of outstanding messages
LONG m_cMessages;
// list of outstanding messages
LIST_ENTRY m_listHead;
//
// synchronization for list
//
CRITICAL_SECTION m_critSec;
//
// to be able to tell if initialization of critsec completed successfully
//
BOOL m_fCritSecInitialized;
//
// Saved failed disconnect hresult, just in case
// the hresult can't be communicated immediately.
//
HRESULT m_hrDisconnect;
//
// Number of outstanding current users of the m_pAcceptor variable
//
ULONG m_cAcceptorUseCount;
// safely increment m_cAcceptorUseCount
VOID
IncrementAcceptorInUse();
// safely decrement m_cAcceptorUseCount and if appropriate, call NotifyPipeDisconnected
VOID
DecrementAcceptorInUse();
// Issue a read for a given size
HRESULT
ReadMessage(DWORD dwReadSize);
// Notify the IPM_MESSAGE_ACCEPTOR exactly once that an error has occurred
VOID
NotifyPipeDisconnected(HRESULT hrError);
}; // IPM_MESSAGE_PIPE
#endif // _PIPEDATA_HXX_