Platform SDK: SMTP Server Events |
[This is preliminary documentation and subject to change.]
Next, we need to add implementations of the ISmtpInCommandSink::OnSmtpInCommand, and the various IPersistPropertyBag methods. For our sink, the implementation of the OnSmtpInCommand method is quite simple. Note that the response text placed in the binding is copied into the global variable g_szResponseText when the IPersistPropertyBag::Load method is called. The size is stored in g_dwResponseSize. The implementation of the OnSmtpInCommand method simply sets the response text, sets the command status to EXPE_DROP_SESSION, and returns the HRESULT value EXPE_S_CONSUMED, indicating to the event dispatcher that this sink has consumed the event.
/* ** ISmtpInCommandSink */ STDMETHODIMP CSink::OnSmtpInCommand( IUnknown *pServer, IUnknown *pSession, IMailMsgProperties *pMsg, ISmtpInCommandContext *pContext) { HRESULT hr = S_OK; if(pContext == NULL) return E_POINTER; char* pszResponse = NULL; long lResponseLength = strlen(g_szResponseText); pszResponse = (char*) CoTaskMemAlloc(g_dwResponseSize); strcpy(pszResponse,g_szResponseText); pszResponse[g_dwResponseSize-1] = '\0'; hr = pContext->SetResponse(pszResponse, g_dwResponseSize); if(FAILED(hr)) return hr; hr = pContext->SetCommandStatus(EXPE_DROP_SESSION); if(FAILED(hr)) return hr; // Success. // Notify the dispatcher that we have // consummed the event. // No other sinks will run, and // the connection will be dropped. return EXPE_S_CONSUMED; }
This is the implementation for IPersistPropertyBag::Load method which is called by the event dispatcher to hand the sink the SinkProperties property bag from the binding:
STDMETHODIMP CSink::Load(IPropertyBag* pBag,IErrorLog *pErrorLog) { if(pBag == NULL) return E_POINTER; if(g_fHaveCustomText) return S_OK; ATLASSERT(pBag); HRESULT hr = S_OK; CComVariant varVal; hr = pBag->Read(L"ResponseText",&varVal,pErrorLog); if(FAILED(hr)) return S_OK; // There's no custom text /* ** We have some custom text */ UINT uiResponseLength = SysStringLen(varVal.bstrVal); char* temp = NULL; temp = new char[uiResponseLength + 1]; if(temp == NULL) return E_OUTOFMEMORY; if(wcstombs(temp,varVal.bstrVal,uiResponseLength+1) == NULL) { delete [] temp; return E_OUTOFMEMORY; } if(g_szResponseText != NULL) delete [] g_szResponseText; g_szResponseText = temp; g_szResponseText[uiResponseLength] = '\0'; g_dwResponseSize = uiResponseLength + 1; g_fHaveCustomText = true; return S_OK; }