521 lines
14 KiB
C++
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
|