⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdkemsviewerruleclient.cpp

📁 WIndows mobile 5.0 pocket pc sdk sample for win32
💻 CPP
📖 第 1 页 / 共 3 页
字号:

    //Get the requested interface
    if(FAILED(hr = pNewComponent->QueryInterface(iid, ppv)))
    {
        RETAILMSG(TRUE, (_T("CFactory::CreateInstance - QueryInterface failed")));
        goto Exit;
    }
    pNewComponent->Release();    
    
Exit:
    return hr;
}


/******************************************************************************

    CFactory::LockServer - COM stuff, used by client to make sure DLL isn't
    unloaded while factory is in use.  In our case the DLL will stay loaded as
    long as tmail.exe is running, so it shouldn't be a real problem, but we 
    have to implement it anyway as part of the IClassFactory interface

    Params:
    bLock[in] - TRUE to add lock, FALSE to release lock

    Returns:
    S_OK - can't really fail.

******************************************************************************/
STDMETHODIMP CFactory::LockServer(BOOL bLock)
{
    if(bLock)
    {
        g_cServerLocks++;
    }
    else
    {
        g_cServerLocks--;
    }

    return S_OK;
}

/******************************************************************************

    CRuleClientBase::CRuleClientBase - C'TOR

******************************************************************************/
CRuleClientBase::CRuleClientBase():
m_cRef(1),
m_mrcAccess(MRC_ACCESS_NONE),
m_mrcHandled(MRC_NOT_HANDLED)
{
}

/******************************************************************************

    CRuleClientBase::~CRuleClientBase - D'TOR

******************************************************************************/
CRuleClientBase::~CRuleClientBase()
{
    RETAILMSG(TRUE, (_T("CRuleClientBase - Destroying self")));
}

/******************************************************************************
******************************************************************************/
HRESULT CRuleClientBase::QueryInterface(const IID& iid, void** ppobj)
{	
    HRESULT hr = E_NOINTERFACE;

    if(!ppobj)
    {
        return E_INVALIDARG;
    }
    
	*ppobj = NULL;
	if((IID_IUnknown == iid) || (IID_IMailRuleClient == iid))
	{
	 	*ppobj = reinterpret_cast<LPVOID>(this);
 	}

    if (*ppobj) 
    {
	 	(reinterpret_cast<IUnknown*>(*ppobj))->AddRef();
		hr = S_OK;
	}
	
	return hr;
}

/******************************************************************************
******************************************************************************/
ULONG CRuleClientBase::AddRef()
{
    return InterlockedIncrement(&m_cRef);
}

/******************************************************************************
******************************************************************************/
ULONG CRuleClientBase::Release()
{
    InterlockedDecrement(&m_cRef);

    int nLocal = m_cRef;

    if(!m_cRef) 
    {
        delete this; 
    }

    return nLocal; 
}

/******************************************************************************

    CRuleClientBase::Initialize - Derived classes need to override

******************************************************************************/
HRESULT CRuleClientBase::Initialize(IMsgStore *pMsgStore, MRCACCESS *pmaDesired)
{
    UNREFERENCED_PARAMETER(pMsgStore);
    UNREFERENCED_PARAMETER(pmaDesired);
    return E_NOTIMPL;
}
            
/******************************************************************************

    CRuleClientBase::ProcessMessage - Derived classes need to override

******************************************************************************/
HRESULT CRuleClientBase::ProcessMessage(IMsgStore *pMsgStore, 
                                        ULONG cbMsg,
                                        LPENTRYID lpMsg, 
                                        ULONG cbDestFolder, 
                                        LPENTRYID lpDestFolder, 
                                        ULONG *pulEventType, 
                                        MRCHANDLED *pHandled)
{
    UNREFERENCED_PARAMETER(pMsgStore);
    UNREFERENCED_PARAMETER(cbMsg);
    UNREFERENCED_PARAMETER(lpMsg);
    UNREFERENCED_PARAMETER(cbDestFolder);
    UNREFERENCED_PARAMETER(lpDestFolder);
    UNREFERENCED_PARAMETER(pulEventType);
    UNREFERENCED_PARAMETER(pHandled);
    return E_NOTIMPL;
}

/******************************************************************************

    CRuleClient_EMS::~CRuleClient_EMS - D'TOR

******************************************************************************/
CRuleClient_EMS::~CRuleClient_EMS()
{
    RETAILMSG(TRUE, (_T("CRuleClient_EMS - Destroying self")));
}

/******************************************************************************

    CRuleClient_EMS::CreateInstance - Each rule client in this DLL must
    implement this function, it's called by CFactory to create each component

    Params:
    pUnknownOuter[in]   - COM aggregation stuff, it will always be null or
                          CFactory won't even call this method, I pass it along
                          in case someday I want to support aggregation, and
                          thus would have to modify CFactory
    ppNewComponent[out] - pointer to component created here

    Returns:
    S_OK on success, or E_OUTOFMEMORY if we can't instantiate the class

******************************************************************************/
HRESULT CRuleClient_EMS::CreateInstance(IUnknown* pUnknownOuter, 
                                        IUnknown** ppNewComponent)
{
    HRESULT hr = S_OK;

    UNREFERENCED_PARAMETER(pUnknownOuter);

    //only CFactory is calling this, ptr* should be good
    *ppNewComponent = new CRuleClient_EMS();

    if(NULL == *ppNewComponent)
    {
        hr = E_OUTOFMEMORY;
    }

    return hr;
}

/******************************************************************************

    CRuleClient_EMS::Initialize - 

******************************************************************************/
HRESULT CRuleClient_EMS::Initialize(IMsgStore *pMsgStore, 
                                    MRCACCESS *pmaDesired)
{
    UNREFERENCED_PARAMETER(pMsgStore);

    RETAILMSG(TRUE, (_T("CRuleClient_EMS::Initialize")));
    
    //Set the Access, Handled, and target string for the client
    m_mrcAccess = MRC_ACCESS_WRITE;
        
    *pmaDesired = m_mrcAccess;

    return S_OK;
}

/******************************************************************************
******************************************************************************/
HRESULT CRuleClient_EMS::ProcessMessage(IMsgStore *pMsgStore, 
                                        ULONG cbMsg,
                                        LPENTRYID lpMsg, 
                                        ULONG cbDestFolder, 
                                        LPENTRYID lpDestFolder,
                                        ULONG *pulEventType, 
                                        MRCHANDLED *pHandled)
{
        SizedSPropTagArray(2, spta) = { 2, PR_CE_EMS_HEADER_DATA, PR_SUBJECT }; 
        HRESULT         hr                      = S_OK;
        IMessage*       pMsg                    = NULL;
        SPropValue*     pspv                    = NULL;
        ULONG           cValues                 = 0;
        MRCHANDLED      mrcHandled              = MRC_NOT_HANDLED;
        UINT            uIndex                  = 0;
static  BOOL            fProcessing             = FALSE;           
static  EMSHEADERINFO   emshi[MAX_EMS_HEADERS]  = {0};
static  UINT            uHeaderCount            = 0;

    //Get the message from the entry ID
    hr = pMsgStore->OpenEntry(cbMsg, lpMsg, NULL, 0, NULL, (LPUNKNOWN *) &pMsg);
    if(FAILED(hr))
    {
        RETAILMSG(TRUE, (_T("CRuleClient_EMS - Unable to get the message!\r\n")));
        goto Exit;
    }
    
    //Try to get the EMS header data
    hr = pMsg->GetProps((SPropTagArray *) &spta, MAPI_UNICODE, &cValues, &pspv);
    if(FAILED(hr))
    {
        //Failed, or it's not an EMS
        RETAILMSG(TRUE, (_T("CRuleClient_EMS - Couldn't get the SM header!\r\n")));
        goto Exit;
    }
    
    //Did we succeed in getting the data, or is there none to get?
    //There might not be any user data, so it could be NULL
    if((2 == cValues) && (NULL != pspv[0].Value.bin.lpb) && (0 != pspv[0].Value.bin.cb))
    {
        /*
        Because the order of the incomming EMS headers can not be assured, we
        have to grab each header (if multipart) then pass them in order to be
        processed.  If we only have one, this is easy.  If we have several, we
        must keep track of the headers collected, determine when we're done,
        then pass the headers to the processing function.  In addition, we'll
        check the IDs of the parts to make sure they all match.  We shouldn't
        get parts of different sequences at the same time.
        */

        //Insert header data into next slot
        if(FAILED(ExtractEMSHeaderInfo(&(emshi[uHeaderCount]),
                                 pspv[0].Value.bin.lpb,
                                 pspv[0].Value.bin.cb,
                                 pspv[1].Value.lpszW)))
        {
            //Massive failure, probably OOM...
            hr = E_FAIL;
            goto Exit;
        }
        fProcessing = TRUE; //got at least one...

        uHeaderCount++;
        if(uHeaderCount >= MAX_EMS_HEADERS)
        {
            //Too many headers...
            hr = E_FAIL;
            goto Exit;
        }

        /*Validate headers. This is needed in case we get a header 
        with a different ID. If this happens we just start over using 
        this header as the first in a new sequence*/
        if(!ValidateHeaders(emshi, uHeaderCount))
        {
            //NYI...reset and store the last header as the first
            //For now just fail
            hr = E_FAIL;
            goto Exit;
        }

        //Check if not done collecting parts
        if((!(emshi[0].fMultiPart)) || !(emshi[0].uNumParts != (uHeaderCount)))
        {
            fProcessing = FALSE;
        }

        //Send the parts to be dealt with
        if(!fProcessing)
        {
            TCHAR*  psz         = NULL;
            UINT    uObjCount   = 0;
            
            //Sort the headers so they get passed in order
            if(1 < uHeaderCount)
            {
                SortHeaderInfo(emshi, uHeaderCount);
            }

            //Process each header
            for(uIndex = 0; uIndex < uHeaderCount; uIndex++)
            {
                //Process each EMS
                if(FAILED(ProcessEMS(emshi[uIndex], &psz, &uObjCount)))
                {
                    //Massive error, maybe OOM...
                    hr = E_FAIL;
                    goto Exit;
                }
            }
            //If we didn't fail above, this should be non-NULL
            ASSERT(psz);
            CBRH((NULL != psz), hr);
            
            //The message class here, is used by the custom form
            //later when the user opens the message for viewing
            WriteEMSToBody(psz, _T("IPM.SMStext.SDKEMS"), pMsg, uObjCount);
            
            free(psz);
        }
        else
        {
            //Still waiting for more, delete this one
            DeleteMessage(pMsgStore, pMsg, cbMsg, lpMsg, cbDestFolder, lpDestFolder, pulEventType, pHandled);
        }

        //We get all EMS...not really the best 'real-world' solution
        //but for this sample don't let any other rules have the message
        mrcHandled = MRC_HANDLED_DONTCONTINUE;
    }
    
Exit:
    if(FAILED(hr) || (!fProcessing))
    {
        fProcessing = FALSE;
        
        //Free header info slots we used
        for(uIndex = 0; uIndex < uHeaderCount; uIndex++)
        {
            FREE_EMSHEADERINFO(emshi[uIndex]);
        }
        uHeaderCount = 0;
    }

    //cleanup
    if(pspv)
    {
        MAPIFreeBuffer(pspv);
    }
    if(pMsg)
    {
        pMsg->Release();
    }
    
    *pHandled = mrcHandled;
    
    return hr;
}


/******************************************************************************

    LibMain - DLL entry point, does a whole lot o' nothing

******************************************************************************/
EXTERN_C BOOL WINAPI LibMain(HINSTANCE hinst, DWORD dwReason, LPVOID lpv)
{
    UNREFERENCED_PARAMETER(lpv);

    g_hInstance = hinst;

    switch(dwReason)
    {
        case DLL_PROCESS_ATTACH:
            break;

        case DLL_PROCESS_DETACH:
            break;
    }

    return TRUE;
}

/******************************************************************************

    DllGetClassObject - COM stuff, client will call this to get interface to
    requested component.  This method delegates that out to 
    CFactory::GetClassObject, which does a lookup of supported components and
    creates the correct one.

******************************************************************************/
STDAPI DllGetClassObject(const CLSID& clsid, const IID& iid, LPVOID *ppv)
{
    HRESULT     hr       = E_FAIL;
    CFactory*   pFactory = NULL;
    
    if(FAILED(hr = CFactory::GetClassObject(clsid, iid, (void**)&pFactory)))
    {
        RETAILMSG(TRUE, (_T("DllGetClassObject - CFactory::GetClassObject failed")));
        goto Exit;
    }

    // Get the requested interface
    if(FAILED(hr = pFactory->QueryInterface(iid, ppv)))
    {
        RETAILMSG(TRUE, (_T("DllGetClassObject - QueryInterface failed")));
        goto Exit;
    }
    pFactory->Release();
    
Exit:
    return hr;
}

/******************************************************************************

    DllCanUnloadNow - COM stuff, client calls this to see if the DLL can be 
    safely unloaded.

******************************************************************************/
STDAPI DllCanUnloadNow()
{
    if(!g_cServerLocks)
    {
        //Save to unload...
        return S_OK;
    }
    else
    {
        return S_FALSE;
    }
}

/******************************************************************************

    DllRegisterServer - COM stuff

******************************************************************************/
STDAPI DllRegisterServer()
{
    return S_OK;
}

/******************************************************************************

    DllUnregisterServer - COM stuff

******************************************************************************/
STDAPI DllUnregisterServer()
{
    return S_OK;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -