2025-04-27 07:49:33 -04:00

426 lines
7.4 KiB
C++

/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
ipm.hxx
Abstract:
This module contains classes for InterProcess Messaging between
the Web Admin Service and the App Pool processes.
Author:
Michael Courage (MCourage) 08-Feb-1999
Revision History:
--*/
#ifndef _IPM_HXX_
#define _IPM_HXX_
//
// constants
//
#define IPM_NAMED_PIPE_NAME L"\\\\.\\pipe\\iisipm"
//
// IPM opcodes
//
enum IPM_OPCODE
{
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_REQUEST_COUNT,
IPM_OP_PERIODIC_PROCESS_RESTART_MEMORY_USAGE_IN_KB,
IPM_OP_PERIODIC_PROCESS_RESTART_SCHEDULE,
IPM_OP_HRESULT
};
//
// 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_MEMORY_LIMIT_REACHED,
IPM_WP_MAXIMUM
};
//
// forwards from elsewhere
//
class STRU;
//
// forward declarations
//
class IO_FACTORY;
class IO_CONTEXT;
class PIPE_IO_HANDLER;
class IPM_PIPE_CONNECTOR;
class IPM_PIPE_FACTORY;
//
// exports
//
class dllexp MESSAGE_GLOBAL;
class dllexp MESSAGE_PIPE;
class dllexp MESSAGE;
//
// MESSAGE
//
// MESSAGE_LISTENERs receive MESSAGE objects through
// their AcceptMessage method.
//
class MESSAGE
{
public:
virtual
DWORD
GetOpcode(
VOID
) const = 0;
virtual
const BYTE *
GetData(
VOID
) const = 0;
virtual
DWORD
GetDataLen(
VOID
) const = 0;
};
//
// MESSAGE_PIPE
//
// This class is an abstraction of a named pipe. You
// send messages through WriteMessages, and receive
// messages by registering MESSAGE_LISTENERs.
//
class MESSAGE_PIPE
{
public:
virtual
HRESULT
WriteMessage(
IN DWORD Port,
IN DWORD DataLen,
IN const BYTE * pData OPTIONAL
) = 0;
virtual
DWORD
GetRemotePid(
VOID
) const = 0;
};
//
// MESSAGE_LISTENER
//
// This is an abstract class that message handlers
// implement to receive messages and status
// information from a MESSAGE_PIPE.
//
class MESSAGE_LISTENER
{
public:
MESSAGE_LISTENER(
VOID
) {}
virtual
~MESSAGE_LISTENER(
VOID
) {}
virtual
HRESULT
AcceptMessage(
IN const MESSAGE * pPipeMessage
) = 0;
virtual
HRESULT
PipeConnected(
VOID
) = 0;
virtual
HRESULT
PipeDisconnected(
IN HRESULT hr
) = 0;
};
//
// MESSAGE_GLOBAL
//
// This class serves as a container for global data,
// and provides the API calls for creating and
// connecting MESSAGE_PIPE objects.
//
class MESSAGE_GLOBAL
{
public:
MESSAGE_GLOBAL(
IN IO_FACTORY * pIoFactory
);
~MESSAGE_GLOBAL(
VOID
);
//
// Setup and teardown.
//
HRESULT
InitializeMessageGlobal(
VOID
);
HRESULT
TerminateMessageGlobal(
VOID
);
//
// Message pipe operations
//
HRESULT
CreateMessagePipe(
IN MESSAGE_LISTENER * pMessageListener,
OUT MESSAGE_PIPE ** ppMessagePipe
);
HRESULT
ConnectMessagePipe(
IN const STRU& strPipeName,
IN DWORD dwId,
IN MESSAGE_PIPE * pMessagePipe
);
HRESULT
AcceptMessagePipeConnection(
IN const STRU& strPipeName,
IN DWORD dwId,
IN MESSAGE_PIPE * pMessagePipe
);
HRESULT
DisconnectMessagePipe(
IN MESSAGE_PIPE * pMessagePipe
);
private:
IPM_PIPE_CONNECTOR * m_pConnector;
IPM_PIPE_FACTORY * m_pPipeFactory;
IO_FACTORY * m_pIoFactory;
};
//
// IO_FACTORY
//
// An abstract factory that can construct
// PIPE_IO_HANDLERs.
//
class IO_FACTORY
{
public:
IO_FACTORY()
{ m_cRefs = 0; };
virtual ~IO_FACTORY()
{ DBG_ASSERT( m_cRefs == 0 ); }
VOID
Reference()
{
InterlockedIncrement(&m_cRefs);
}
VOID
Dereference()
{
if (!InterlockedDecrement(&m_cRefs)) {
delete this;
}
}
virtual
HRESULT
CreatePipeIoHandler(
IN HANDLE hPipe,
OUT PIPE_IO_HANDLER ** ppPipeIoHandler
) = 0;
virtual
HRESULT
ClosePipeIoHandler(
IN PIPE_IO_HANDLER * pPipeIoHandler
) = 0;
private:
LONG m_cRefs;
};
//
// PIPE_IO_HANDLER
//
// An abstract class that can do async I/O operations
// on a named pipe in its host process.
//
// On I/O completions the handler must call
// pContext->NotifyIoCompletion with the results.
//
#define PIPE_IO_HANDLER_SIGNATURE CREATE_SIGNATURE( 'PIOH' )
#define PIPE_IO_HANDLER_SIGNATURE_FREED CREATE_SIGNATURE( 'xpio' )
class PIPE_IO_HANDLER
{
public:
PIPE_IO_HANDLER(
IN const HANDLE hPipe
) : m_dwSignature(PIPE_IO_HANDLER_SIGNATURE),
m_hPipe(hPipe) {}
virtual
~PIPE_IO_HANDLER(
VOID
)
{ CheckSignature(); m_dwSignature = PIPE_IO_HANDLER_SIGNATURE_FREED; }
VOID
CheckSignature()
{ DBG_ASSERT( m_dwSignature == PIPE_IO_HANDLER_SIGNATURE ); }
virtual
HRESULT
Connect(
IN IO_CONTEXT * pContext,
IN PVOID pv
) = 0;
virtual
HRESULT
Disconnect(
VOID
) = 0;
virtual
HRESULT
Write(
IN IO_CONTEXT * pContext,
IN PVOID pv,
IN const BYTE * pBuff,
IN DWORD cbBuff
) = 0;
virtual
HRESULT
Read(
IN IO_CONTEXT * pContext,
IN PVOID pv,
IN BYTE * pBuff,
IN DWORD cbBuff
) = 0;
protected:
HANDLE
GetHandle(
VOID
) const
{ return m_hPipe; }
private:
DWORD m_dwSignature;
const HANDLE m_hPipe;
};
//
// IO_CONTEXT
//
// A class that receives I/O completion notifications.
//
class IO_CONTEXT
{
public:
virtual
HRESULT
NotifyConnectCompletion(
IN PVOID pv,
IN DWORD cbTransferred,
IN HRESULT hr
) = 0;
virtual
HRESULT
NotifyReadCompletion(
IN PVOID pv,
IN DWORD cbTransferred,
IN HRESULT hr
) = 0;
virtual
HRESULT
NotifyWriteCompletion(
IN PVOID pv,
IN DWORD cbTransferred,
IN HRESULT hr
) = 0;
};
//
// the stupid hack section
//
dllexp
HRESULT
IpmReadFile(
HANDLE hFile,
PVOID pBuffer,
DWORD cbBuffer,
LPOVERLAPPED pOverlapped
);
dllexp
HRESULT
IpmWriteFile(
HANDLE hFile,
PVOID pBuffer,
DWORD cbBuffer,
LPOVERLAPPED pOverlapped
);
#endif // _IPM_HXX_