426 lines
7.4 KiB
C++
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_
|
|
|