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

📄 q.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//=--------------------------------------------------------------------------=
// MSMQQueueObj.Cpp
//=--------------------------------------------------------------------------=
//
// the MSMQQueue object
//
//
#include "IPServer.H"

#include "LocalObj.H"
#include "dispids.h"


#include "oautil.h"
#include "q.H"
#include "msg.h"
#include "qinfo.h"
// #include "txdtc.h"             // transaction support.
// #include "xact.h"

extern UINT OrdinalOfPropId(MQMSGPROPS *pmsgprops, MSGPROPID propid);
// extern HRESULT GetCurrentViperTransaction(ITransaction **pptransaction);


// for ASSERT and FAIL
//
SZTHISFILE

// debug...
#define new DEBUG_NEW
#if DEBUG
#define SysAllocString DebSysAllocString
#define SysReAllocString DebSysReAllocString
#define SysFreeString DebSysFreeString
#endif // DEBUG

// Used to coordinate user-thread queue ops and 
//  queue lookup in falcon-thread callback 
//
extern CRITICAL_SECTION g_csCallback;

// Global list of MSMQQueue instances
// Used to map queue handle to queue object
//
QueueNode *CMSMQQueue::m_pqnodeFirst = NULL;

// Global list of callback params
CallbackNode *CMSMQQueue::m_pcallbacknodeFirst = NULL;

// defined in MSMQMessage
extern PROPREC g_rgmsgproprec[];
extern ULONG g_cPropRec;
#if 0
extern PROPREC g_rgproprecAsyncReceive[];
extern ULONG g_cPropRecAsyncReceive;
#endif // 0

/* helper: provided by msg.cpp
extern HRESULT GetOptionalTransaction(
    VARIANT *pvarTransaction,
    ITransaction **pptransaction,
    BOOL *pisRealXact);
*/

//=--------------------------------------------------------------------------=
// HELPER::InitMessageProps
//=--------------------------------------------------------------------------=
// Inits MQMSGPROPS struct.  
//
// Parameters:
//
// Output:
//
// Notes:
//
void InitMessageProps(MQMSGPROPS *pmsgprops)
{
    pmsgprops->aPropID = NULL;
    pmsgprops->aPropVar = NULL;
    pmsgprops->aStatus = NULL;
}

//=--------------------------------------------------------------------------=
// CMSMQQueue::AddQueue, RemQueue, PqOfHandle
//=--------------------------------------------------------------------------=
// Static instance list manipulation methods
//
// Parameters:
//    pq    [in]  queue to be added to list
//
// Output:
//
// Notes:
//    pq is not addref'ed.
//    We critsect queue closure/removal and the callback.
//
HRESULT CMSMQQueue::AddQueue(CMSMQQueue *pq)
{
    QueueNode *pqnode;
    HRESULT hresult = NOERROR;


    pqnode = new QueueNode;
    if (pqnode == NULL) {
      hresult = E_OUTOFMEMORY;
    }
    else {
      EnterCriticalSection(&g_csCallback);    // synchs falcon callback queue lookup
      // cons
      pqnode->m_pq = pq;
      pqnode->m_pqnodeNext = m_pqnodeFirst;
      m_pqnodeFirst = pqnode;
      LeaveCriticalSection(&g_csCallback);    // synchs falcon callback queue lookup
    }

    return hresult;
}


HRESULT CMSMQQueue::RemQueue(CMSMQQueue *pq)
{
    EnterCriticalSection(&g_csCallback);    // synchs falcon callback queue lookup
    QueueNode *pqnodeCur = m_pqnodeFirst;
    QueueNode *pqnodePrev = NULL;
    HRESULT hresult = NOERROR;


    while (pqnodeCur) {
      if (pqnodeCur->m_pq == pq) {

        // remove
        if (pqnodePrev) {
          pqnodePrev->m_pqnodeNext = pqnodeCur->m_pqnodeNext;
        }
        else {
          m_pqnodeFirst = pqnodeCur->m_pqnodeNext;
        }
        delete pqnodeCur;
        break;
      }
      pqnodePrev = pqnodeCur;
      pqnodeCur = pqnodeCur->m_pqnodeNext;
    } // while

    LeaveCriticalSection(&g_csCallback);    // synchs falcon callback queue lookup
    return hresult;
}


CMSMQQueue *CMSMQQueue::PqOfHandle(QUEUEHANDLE lHandle)
{
    QueueNode *pqnodeCur = m_pqnodeFirst;
    CMSMQQueue *pq = NULL;

    while (pqnodeCur) {
      if (pqnodeCur->m_pq->m_lHandle == lHandle) {
        pq = pqnodeCur->m_pq;
        break;
      }
      pqnodeCur = pqnodeCur->m_pqnodeNext;
    } // while

    return pq;
}


// helpers
// helper: free body buffer
void FreeBodyBuffer(
    MQMSGPROPS* pmsgprops, 
    UINT iBody)
{
    HGLOBAL hMem = NULL;
    CAUB *pcau = &pmsgprops->aPropVar[iBody].caub;

    if (pcau->pElems) {
      hMem = GlobalHandle(pcau->pElems);
      ASSERT(hMem, L"bad handle.");
      GLOBALFREE(hMem);
      pcau->pElems = NULL;
    }

}

// helper: (re)allocate body buffer
HGLOBAL AllocateBodyBuffer(
    MQMSGPROPS* pmsgprops, 
    UINT iBody, 
    DWORD dwBodySize)
{
    HGLOBAL hMem = NULL;
    CAUB *pcau;

    // 
    // free current body if any
    //
    FreeBodyBuffer(pmsgprops, iBody);
    //
    // Allocating buffer
    //
    pmsgprops->aPropVar[iBody].caub.cElems = dwBodySize;
    pcau = &pmsgprops->aPropVar[iBody].caub;
    IfNullGo(hMem = GLOBALALLOC_MOVEABLE_NONDISCARD(pcau->cElems));
    pcau->pElems = (UCHAR *)GlobalLock(hMem);
    GLOBALUNLOCK(hMem);

    // fall through...

Error:
    return hMem;
}

//
// HELPER: get optional timeout param
//  defaults to INFINITE
//
HRESULT GetOptionalReceiveTimeout(
    VARIANT *pvarReceiveTimeout,
    long *plReceiveTimeout)
{
    long lReceiveTimeout = INFINITE;
    HRESULT hresult = NOERROR;

    if (pvarReceiveTimeout) {
      if (V_VT(pvarReceiveTimeout) != VT_ERROR) {
        IfFailRet(VariantChangeType(pvarReceiveTimeout, 
                                    pvarReceiveTimeout, 
                                    0, 
                                    VT_I4));
        lReceiveTimeout = V_I4(pvarReceiveTimeout);
      }
    }
    *plReceiveTimeout = lReceiveTimeout;

    return hresult;
}


// forwards decls...
void APIENTRY ReceiveCallback(
    HRESULT hrStatus,
    QUEUEHANDLE hReceiveQueue,
    DWORD dwTimeout,
    DWORD dwAction,
    MQMSGPROPS* pmsgprops,
    LPOVERLAPPED lpOverlapped,
    HANDLE hCursor);
void APIENTRY ReceiveCallbackCurrent(
    HRESULT hrStatus,
    QUEUEHANDLE hReceiveQueue,
    DWORD dwTimeout,
    DWORD dwAction,
    MQMSGPROPS* pmsgprops,
    LPOVERLAPPED lpOverlapped,
    HANDLE hCursor);
void APIENTRY ReceiveCallbackNext(
    HRESULT hrStatus,
    QUEUEHANDLE hReceiveQueue,
    DWORD dwTimeout,
    DWORD dwAction,
    MQMSGPROPS* pmsgprops,
    LPOVERLAPPED lpOverlapped,
    HANDLE hCursor);


//=--------------------------------------------------------------------------=
// CMSMQQueue::Create
//=--------------------------------------------------------------------------=
// creates a new MSMQQueue object.
//
// Parameters:
//    IUnknown *        - [in] controlling unkonwn
//
// Output:
//    IUnknown *        - new object.
//
// Notes:
//
IUnknown *CMSMQQueue::Create
(
    IUnknown *pUnkOuter
)
{
    // make sure we return the private unknown so that we support aggegation
    // correctly!
    //
    CMSMQQueue *pNew = new CMSMQQueue(pUnkOuter);
    return pNew ? pNew->PrivateUnknown() : NULL;
}

//=--------------------------------------------------------------------------=
// CMSMQQueue::CMSMQQueue
//=--------------------------------------------------------------------------=
// create the object and initialize the refcount
//
// Parameters:
//    IUnknown *    - [in] controlling unknown
//
// Notes:
//
#pragma warning(disable:4355)  // using 'this' in constructor
CMSMQQueue::CMSMQQueue
(
    IUnknown *pUnkOuter
)
: CAutomationObject(pUnkOuter, OBJECT_TYPE_OBJMQQUEUE, (void *)this)
{

    // TODO: initialize anything here
    m_lAccess = 0;                  
    m_lShareMode = MQ_DENY_NONE;               
    m_pqinfo = NULL;
    m_lHandle = INVALID_HANDLE_VALUE;
    m_hCursor = 0;
    m_pqevent = NULL;
    m_hasActiveEventHandler = FALSE;
}
#pragma warning(default:4355)  // using 'this' in constructor

//=--------------------------------------------------------------------------=
// CMSMQQueue::CMSMQQueue
//=--------------------------------------------------------------------------=
// "We all labour against our own cure, for death is the cure of all diseases"
//    - Sir Thomas Browne (1605 - 82)
//
// Notes:
//
CMSMQQueue::~CMSMQQueue ()
{
    // TODO: clean up anything here.
    HRESULT hresult;

    // remove from global instance list
    RemQueue(this);
    RELEASE(m_pqinfo);
    RELEASE(m_pqevent);
    hresult = Close();
    ASSERT(SUCCEEDED(hresult), L"whoops! can't handle errors here.");
}


//=--------------------------------------------------------------------------=
// CMSMQQueue::InternalQueryInterface
//=--------------------------------------------------------------------------=
// the controlling unknown will call this for us in the case where they're
// looking for a specific interface.
//
// Parameters:
//    REFIID        - [in]  interface they want
//    void **       - [out] where they want to put the resulting object ptr.
//
// Output:
//    HRESULT       - S_OK, E_NOINTERFACE
//
// Notes:
//
HRESULT CMSMQQueue::InternalQueryInterface
(
    REFIID riid,
    void **ppvObjOut
)
{

⌨️ 快捷键说明

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