windows-nt/Source/XPSP1/NT/inetsrv/iis/svcs/smtp/server/cpropbag.h
2020-09-26 16:20:57 +08:00

521 lines
14 KiB
C++

/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
cpropbag.h
Abstract:
This module contains the definition of the
generic property bag class
Author:
Keith Lau (keithlau@microsoft.com)
Revision History:
keithlau 06/30/98 created
--*/
#ifndef _CPROPBAG_H_
#define _CPROPBAG_H_
#include "filehc.h"
#include "mailmsg.h"
#include "cmmtypes.h"
#include "cleanback.h"
//
//Logging facilities
//
#include "inetcom.h"
#include "logtype.h"
/***************************************************************************/
// Definitions
//
#define GENERIC_PTABLE_INSTANCE_SIGNATURE_VALID ((DWORD)'PTGv')
/***************************************************************************/
// CMailMsgPropertyBag
//
//
// Disable warning about using the this pointer in the constructor
// (CCleanBack only saves the pointer, so this is safe)
//
#pragma warning( disable: 4355 )
class CMailMsgPropertyBag :
public IMailMsgPropertyBag,
public CCleanBack
{
public:
CMailMsgPropertyBag() :
CCleanBack((IUnknown *)(IMailMsgPropertyBag *)this),
m_bmBlockManager(NULL),
m_ptProperties(
PTT_PROPERTY_TABLE,
GENERIC_PTABLE_INSTANCE_SIGNATURE_VALID,
&m_bmBlockManager,
&m_InstanceInfo,
CompareProperty,
NULL,
NULL
)
{
m_lRefCount = 1;
// Copy the default instance into our instance
MoveMemory(
&m_InstanceInfo,
&s_DefaultInstanceInfo,
sizeof(PROPERTY_TABLE_INSTANCE));
}
~CMailMsgPropertyBag()
{
//
// Call all registered callbacks BEFORE destroying member
// variables (so that properties will still be accessible)
//
CallCallBacks();
}
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID *ppvObj)
{
if (riid == IID_IUnknown)
*ppvObj = (IUnknown *)(IMailMsgPropertyBag *)this;
else if (riid == IID_IMailMsgPropertyBag)
*ppvObj = (IMailMsgPropertyBag *)this;
else if (riid == IID_IMailMsgRegisterCleanupCallback)
*ppvObj = (IMailMsgRegisterCleanupCallback *)this;
else
return(E_NOINTERFACE);
AddRef();
return(S_OK);
}
unsigned long STDMETHODCALLTYPE AddRef()
{
return(InterlockedIncrement(&m_lRefCount));
}
unsigned long STDMETHODCALLTYPE Release()
{
LONG lTemp = InterlockedDecrement(&m_lRefCount);
if (!lTemp)
{
// Extra releases are bad!
_ASSERT(lTemp);
}
return(lTemp);
}
HRESULT STDMETHODCALLTYPE PutProperty(
DWORD dwPropID,
DWORD cbLength,
LPBYTE pbValue
)
{
GLOBAL_PROPERTY_ITEM piItem;
piItem.idProp = dwPropID;
return(m_ptProperties.PutProperty(
(LPVOID)&dwPropID,
(LPPROPERTY_ITEM)&piItem,
cbLength,
pbValue));
}
HRESULT STDMETHODCALLTYPE GetProperty(
DWORD dwPropID,
DWORD cbLength,
DWORD *pcbLength,
LPBYTE pbValue
)
{
GLOBAL_PROPERTY_ITEM piItem;
return(m_ptProperties.GetPropertyItemAndValue(
(LPVOID)&dwPropID,
(LPPROPERTY_ITEM)&piItem,
cbLength,
pcbLength,
pbValue));
}
HRESULT STDMETHODCALLTYPE PutStringA(
DWORD dwPropID,
LPCSTR pszValue
)
{
return(PutProperty(dwPropID, pszValue?strlen(pszValue)+1:0, (LPBYTE)pszValue));
}
HRESULT STDMETHODCALLTYPE GetStringA(
DWORD dwPropID,
DWORD cchLength,
LPSTR pszValue
)
{
DWORD dwLength;
return(GetProperty(dwPropID, cchLength, &dwLength, (LPBYTE)pszValue));
}
HRESULT STDMETHODCALLTYPE PutStringW(
DWORD dwPropID,
LPCWSTR pszValue
)
{
return(PutProperty(dwPropID, pszValue?(wcslen(pszValue)+1)*sizeof(WCHAR):0, (LPBYTE)pszValue));
}
HRESULT STDMETHODCALLTYPE GetStringW(
DWORD dwPropID,
DWORD cchLength,
LPWSTR pszValue
)
{
DWORD dwLength;
return(GetProperty(dwPropID, cchLength*sizeof(WCHAR), &dwLength, (LPBYTE)pszValue));
}
HRESULT STDMETHODCALLTYPE PutDWORD(
DWORD dwPropID,
DWORD dwValue
)
{
return(PutProperty(dwPropID, sizeof(DWORD), (LPBYTE)&dwValue));
}
HRESULT STDMETHODCALLTYPE GetDWORD(
DWORD dwPropID,
DWORD *pdwValue
)
{
DWORD dwLength;
return(GetProperty(dwPropID, sizeof(DWORD), &dwLength, (LPBYTE)pdwValue));
}
HRESULT STDMETHODCALLTYPE PutBool(
DWORD dwPropID,
DWORD dwValue
)
{
dwValue = dwValue ? 1 : 0;
return(PutProperty(dwPropID, sizeof(DWORD), (LPBYTE)&dwValue));
}
HRESULT STDMETHODCALLTYPE GetBool(
DWORD dwPropID,
DWORD *pdwValue
)
{
HRESULT hrRes;
DWORD dwLength;
hrRes = GetProperty(dwPropID, sizeof(DWORD), &dwLength, (LPBYTE)pdwValue);
if (pdwValue)
*pdwValue = *pdwValue ? 1 : 0;
return (hrRes);
}
private:
// The specific compare function for this type of property table
static HRESULT CompareProperty(
LPVOID pvPropKey,
LPPROPERTY_ITEM pItem
);
private:
// Usage count
LONG m_lRefCount;
// Property table instance
PROPERTY_TABLE_INSTANCE m_InstanceInfo;
static PROPERTY_TABLE_INSTANCE s_DefaultInstanceInfo;
// IMailMsgProperties is an instance of CPropertyTable
CPropertyTable m_ptProperties;
// An instance of the block memory manager
CBlockManager m_bmBlockManager;
};
//
// Restore original warning settings
//
#pragma warning ( default: 4355 )
/***************************************************************************/
// CMailMsgLoggingPropertyBag
//
class __declspec(uuid("58f9a2d2-21ca-11d2-aa6b-00c04fa35b82")) CMailMsgLoggingPropertyBag :
public CMailMsgPropertyBag,
public IMailMsgLoggingPropertyBag
{
public:
CMailMsgLoggingPropertyBag()
{
m_lRefCount = 1;
m_pvLogHandle = NULL;
}
HRESULT STDMETHODCALLTYPE PutProperty(
DWORD dwPropID,
DWORD cbLength,
LPBYTE pbValue
)
{
HRESULT hrRes = S_OK;
m_rwLock.ExclusiveLock();
hrRes = CMailMsgPropertyBag::PutProperty(
dwPropID,
cbLength,
pbValue);
m_rwLock.ExclusiveUnlock();
return(hrRes);
}
HRESULT STDMETHODCALLTYPE GetProperty(
DWORD dwPropID,
DWORD cbLength,
DWORD *pcbLength,
LPBYTE pbValue
)
{
HRESULT hrRes = S_OK;
m_rwLock.ExclusiveLock();
hrRes = CMailMsgPropertyBag::GetProperty(
dwPropID,
cbLength,
pcbLength,
pbValue);
m_rwLock.ExclusiveUnlock();
return(hrRes);
}
HRESULT STDMETHODCALLTYPE PutStringA(
DWORD dwPropID,
LPCSTR pszValue
)
{
return(PutProperty(dwPropID, pszValue?strlen(pszValue)+1:0, (LPBYTE)pszValue));
}
HRESULT STDMETHODCALLTYPE GetStringA(
DWORD dwPropID,
DWORD cchLength,
LPSTR pszValue
)
{
DWORD dwLength;
return(GetProperty(dwPropID, cchLength, &dwLength, (LPBYTE)pszValue));
}
HRESULT STDMETHODCALLTYPE PutStringW(
DWORD dwPropID,
LPCWSTR pszValue
)
{
return(PutProperty(dwPropID, pszValue?(wcslen(pszValue)+1)*sizeof(WCHAR):0, (LPBYTE)pszValue));
}
HRESULT STDMETHODCALLTYPE GetStringW(
DWORD dwPropID,
DWORD cchLength,
LPWSTR pszValue
)
{
DWORD dwLength;
return(GetProperty(dwPropID, cchLength*sizeof(WCHAR), &dwLength, (LPBYTE)pszValue));
}
HRESULT STDMETHODCALLTYPE PutDWORD(
DWORD dwPropID,
DWORD dwValue
)
{
return(PutProperty(dwPropID, sizeof(DWORD), (LPBYTE)&dwValue));
}
HRESULT STDMETHODCALLTYPE GetDWORD(
DWORD dwPropID,
DWORD *pdwValue
)
{
DWORD dwLength;
return(GetProperty(dwPropID, sizeof(DWORD), &dwLength, (LPBYTE)pdwValue));
}
HRESULT STDMETHODCALLTYPE PutBool(
DWORD dwPropID,
DWORD dwValue
)
{
dwValue = dwValue ? 1 : 0;
return(PutProperty(dwPropID, sizeof(DWORD), (LPBYTE)&dwValue));
}
HRESULT STDMETHODCALLTYPE GetBool(
DWORD dwPropID,
DWORD *pdwValue
)
{
HRESULT hrRes;
DWORD dwLength;
hrRes = GetProperty(dwPropID, sizeof(DWORD), &dwLength, (LPBYTE)pdwValue);
if (pdwValue)
*pdwValue = *pdwValue ? 1 : 0;
return (hrRes);
}
HRESULT SetLogging(
LPVOID pvLogHandle
)
{
if (!pvLogHandle)
return(E_POINTER);
m_pvLogHandle = pvLogHandle;
return(S_OK);
}
static void SetInetLogInfoField(
LPCSTR pszInput,
LPSTR *ppszOutput,
DWORD *pdwOutput
)
{
if (pszInput)
{
*ppszOutput = (LPSTR) pszInput;
if (pdwOutput)
*pdwOutput = lstrlen(pszInput);
}
}
unsigned long STDMETHODCALLTYPE AddRef()
{
return(InterlockedIncrement(&m_lRefCount));
}
unsigned long STDMETHODCALLTYPE Release()
{
LONG lTemp = InterlockedDecrement(&m_lRefCount);
if (!lTemp)
{
// Extra releases are bad!
_ASSERT(lTemp);
}
return(lTemp);
}
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID *ppvObj)
{
if (riid == IID_IUnknown)
*ppvObj = (IUnknown *)(IMailMsgLoggingPropertyBag *)this;
else if (riid == IID_IMailMsgLoggingPropertyBag)
*ppvObj = (IMailMsgLoggingPropertyBag *)this;
else if (riid == __uuidof(CMailMsgLoggingPropertyBag))
*ppvObj = (CMailMsgLoggingPropertyBag *)this;
else if (riid == IID_IMailMsgPropertyBag)
*ppvObj = (IMailMsgPropertyBag *)
((IMailMsgLoggingPropertyBag *)this);
else if (riid == IID_IMailMsgRegisterCleanupCallback)
*ppvObj = (IMailMsgRegisterCleanupCallback *)this;
else
return(E_NOINTERFACE);
AddRef();
return(S_OK);
}
static DWORD LoggingHelper(
LPVOID pvLogHandle,
const INETLOG_INFORMATION *pLogInformation
);
HRESULT STDMETHODCALLTYPE WriteToLog(
LPCSTR pszClientHostName,
LPCSTR pszClientUserName,
LPCSTR pszServerAddress,
LPCSTR pszOperation,
LPCSTR pszTarget,
LPCSTR pszParameters,
LPCSTR pszVersion,
DWORD dwBytesSent,
DWORD dwBytesReceived,
DWORD dwProcessingTimeMS,
DWORD dwWin32Status,
DWORD dwProtocolStatus,
DWORD dwPort,
LPCSTR pszHTTPHeader
)
{
INETLOG_INFORMATION info;
DWORD dwRes;
memset(&info,0,sizeof(info));
SetInetLogInfoField(pszClientHostName,&info.pszClientHostName,&info.cbClientHostName);
SetInetLogInfoField(pszClientUserName,&info.pszClientUserName,NULL);
SetInetLogInfoField(pszServerAddress,&info.pszServerAddress,NULL);
SetInetLogInfoField(pszOperation,&info.pszOperation,&info.cbOperation);
SetInetLogInfoField(pszTarget,&info.pszTarget,&info.cbTarget);
SetInetLogInfoField(pszParameters,&info.pszParameters,NULL);
SetInetLogInfoField(pszVersion,&info.pszVersion,NULL);
info.dwBytesSent = dwBytesSent;
info.dwBytesRecvd = dwBytesReceived;
info.msTimeForProcessing = dwProcessingTimeMS;
info.dwWin32Status = dwWin32Status;
info.dwProtocolStatus = dwProtocolStatus;
info.dwPort = dwPort;
SetInetLogInfoField(pszHTTPHeader,&info.pszHTTPHeader,&info.cbHTTPHeaderSize);
dwRes = LoggingHelper(m_pvLogHandle,&info);
return(S_OK);
}
private:
// Usage count
LONG m_lRefCount;
LPVOID m_pvLogHandle;
CShareLockNH m_rwLock;
};
// =================================================================
// Compare function
//
inline HRESULT CMailMsgPropertyBag::CompareProperty(
LPVOID pvPropKey,
LPPROPERTY_ITEM pItem
)
{
if (*(PROP_ID *)pvPropKey == ((LPGLOBAL_PROPERTY_ITEM)pItem)->idProp)
return(S_OK);
return(STG_E_UNKNOWN);
}
#endif