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

📄 msg.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
//    Supports intrinsic variant types
//
HRESULT CMSMQMessage::PutVarBody(VARIANT varBody)
{
    VARTYPE vt = V_VT(&varBody);
    void *pvBody;
    HRESULT hresult = NOERROR;
  
    
	EnterCriticalSection(&m_CSlocal);

    // UNDONE: VT_BYREF?
    switch (vt) {
    case VT_I2:
    case VT_UI2:
      m_cbBody = 2;
      pvBody = &varBody.iVal;
      break;
    case VT_I4:
    case VT_UI4:
      m_cbBody = 4;
      pvBody = &varBody.lVal;
      break;
    case VT_R4:
      m_cbBody = 4;
      pvBody = &varBody.fltVal;
    case VT_R8:
      m_cbBody = 8;
      pvBody = &varBody.dblVal;
      break;
    case VT_CY:
      m_cbBody = sizeof(CY);
      pvBody = &varBody.cyVal;
      break;
    case VT_DATE:
      m_cbBody = sizeof(DATE);
      pvBody = &varBody.date;
      break;
    case VT_BOOL:
      m_cbBody = sizeof(VARIANT_BOOL);
      pvBody = &varBody.boolVal;
      break;
    case VT_I1:
    case VT_UI1:
      m_cbBody = 1;
      pvBody = &varBody.bVal;
      break;
    case VT_BSTR:
      BSTR bstrBody;

      IfFailGo(GetTrueBstr(&varBody, &bstrBody));
      m_cbBody = SysStringByteLen(bstrBody);
      pvBody = bstrBody;
      break;
    default:
      IfFailGo(hresult = E_INVALIDARG);
      break;
    } // switch
    m_vtBody = vt;
    hresult = UpdateBodyBuffer((ULONG)m_cbBody, pvBody ? pvBody : L"");
    // fall through...

Error:
	
	LeaveCriticalSection(&m_CSlocal);
    return CreateErrorHelper(hresult, m_ObjectType);
}


//=--------------------------------------------------------------------------=
// CMSMQMessage::PutBinBody
//=--------------------------------------------------------------------------=
// Sets message body
//
// Parameters:
//    psaBody - [in] binary message body
//
// Output:
//
// Notes:
//    Supports arrays of any type
//     and persistent ActiveX objects:
//     i.e. objects that support IPersistStream | IPersistStorage
//           and IDispatch.
//

HRESULT CMSMQMessage::PutBinBody(VARIANT varBody)
{

    SAFEARRAY *psa = NULL;
    UINT nDim, i, cbElem, cbBody;
    long lLBound, lUBound;
    VOID *pvData;
    VARTYPE vt = varBody.vt;
    IPersistStream *ppersstm = NULL;
    IPersistStorage *ppersstg = NULL;
    
#if 0 // not used outside of "unimplemented" areas
    IUnknown *punk = NULL;
    IDispatch *pdisp = NULL;
 	LARGE_INTEGER li;
    ULARGE_INTEGER ulibMax;
    STATSTG statstg;
#endif // 0 

    MSGTYPE msgtype;
    ILockBytes *plockbytes = NULL;
    IStream *pstm = NULL;
    IStorage *pstg = NULL;
    BOOL	bLocked = FALSE;
    HRESULT hresult = NOERROR;

    cbBody = 0;
    GLOBALFREE(m_hMem);
    m_pbBody = NULL;

    switch (vt) {
    case VT_DISPATCH:

		return E_INVALIDARG;
#if 0 // not implemented
      //
      // QI to IPersistStream
      //
      pdisp = varBody.pdispVal;
      if (pdisp == NULL) {
        return E_INVALIDARG;
      }
      hresult = pdisp->QueryInterface(IID_IPersistStream,
                                     (LPVOID *)&ppersstm);

      // try IPersistStorage...
      if (FAILED(hresult)) {
        IfFailGo(pdisp->QueryInterface(IID_IPersistStorage,
                                       (LPVOID *)&ppersstg));
        msgtype = MSGTYPE_STORAGE;
      }
      else {
        msgtype = MSGTYPE_STREAM;
      }
 #endif // 0 not implemented
      break;
    case VT_UNKNOWN:
		return E_INVALIDARG;
#if 0 // not implemnented
      //
      // QI to IPersistStream
      //
      punk = varBody.punkVal;
      if (punk == NULL) {
        return E_INVALIDARG;
      }
      //
      hresult = punk->QueryInterface(IID_IPersistStream,
                                     (LPVOID *)&ppersstm);

      // try IPersistStorage...
      if (FAILED(hresult)) {
        IfFailGo(punk->QueryInterface(IID_IPersistStorage,
                                      (LPVOID *)&ppersstg));
        msgtype = MSGTYPE_STORAGE;
      }
      else {
        msgtype = MSGTYPE_STREAM;
      }
#endif // 0 not implemented
      break;
    default:
      msgtype = MSGTYPE_BINARY;
    } // switch

	
	// Lock us down so other threads won't write a message behind our backs
	EnterCriticalSection(&m_CSlocal);
	bLocked = TRUE;
    //
    // allocate new global handle of size 0
    //
    IfNullFail(m_hMem = GLOBALALLOC_MOVEABLE_NONDISCARD(0));
    switch (msgtype) {
    case MSGTYPE_STREAM:
#if 0 // not implemented

      hresult = CreateStreamOnHGlobal(
                  m_hMem, // NULL,   // hGlobal
                  FALSE,  // TRUE,   // fDeleteOnRelease
                  &pstm);

      // reset stream seek pointer
      LISet32(li, 0);
      IfFailGo(pstm->Seek(li, STREAM_SEEK_SET, NULL));

      // save
      IfFailGo(OleSaveToStream(ppersstm, pstm));

      // How big is our stream?
      IfFailGo(pstm->Stat(&statstg, STATFLAG_NONAME));
      ulibMax = statstg.cbSize;
      if (ulibMax.HighPart != 0) {
        IfFailGo(hresult = E_INVALIDARG);
      }
      cbBody = ulibMax.LowPart;
      m_vtBody = VT_STREAMED_OBJECT;
 #endif // 0
      break;
    case MSGTYPE_BINARY:
      //
      // array: compute byte count
      //
      psa = varBody.parray;
      if (psa) {
        nDim = SafeArrayGetDim(psa);
        cbElem = SafeArrayGetElemsize(psa);
        for (i = 1; i <= nDim; i++) {
          IfFailGo(SafeArrayGetLBound(psa, i, &lLBound));
          IfFailGo(SafeArrayGetUBound(psa, i, &lUBound));
          cbBody += (lUBound - lLBound + 1) * cbElem;
        }
        IfFailGo(SafeArrayAccessData(psa, &pvData));
        IfFailGo(UpdateBodyBuffer(cbBody, pvData));
      }
      m_vtBody = VT_ARRAY | VT_UI1;
      break;
    case MSGTYPE_STORAGE:
#if 0 // not implemented
      //
      // Always create a new storage object.
      // REVIEW: Be nice if, as we do for streams, we could
      //  cache an in-memory storage and reuse --
      //  but I know of no way to reset a storage.
      //
      IfFailGo(CreateILockBytesOnHGlobal(
                  m_hMem, // NULL,  // hGlobal
                  FALSE,  // TRUE,  // fDeleteOnRelease
                  &plockbytes));
      IfFailGo(StgCreateDocfileOnILockBytes(
                 plockbytes,
                 STGM_CREATE |
                  STGM_READWRITE |
                  STGM_SHARE_EXCLUSIVE,
                 0,             //Reserved; must be zero
                 &pstg));
      IfFailGo(OleSave(ppersstg, pstg, FALSE /* fSameAsLoad */));
#if DEBUG
      STATSTG statstg2;

      IfFailGo(pstg->Stat(&statstg2, STATFLAG_NONAME));
      DWORD cbSize;
	  // use LocalSize on WinCE
      cbSize = LocalSize(m_hMem);
#endif // DEBUG

      // now get underlying ILockBytes stats
      IfFailGo(plockbytes->Stat(&statstg, STATFLAG_NONAME));
      ulibMax = statstg.cbSize;
      ASSERT(ulibMax.HighPart == 0, L"storage too large.");
      cbBody = ulibMax.LowPart;
      m_vtBody = VT_STORED_OBJECT;
#endif // 0
      break;
    default:
      ASSERT(0, L"unreachable?");
      break;
    } // switch

    m_cbBody = cbBody;
    m_pbBody = (BYTE *)GlobalLock(m_hMem);
    ASSERT(m_pbBody, L"should have valid pointer.");
    GLOBALUNLOCK(m_hMem);

    // fall through...

Error:
	if(bLocked)
		LeaveCriticalSection(&m_CSlocal);
		
    if (psa) {
      SafeArrayUnaccessData(psa);
    }
    RELEASE(ppersstm);
    RELEASE(ppersstg);
    RELEASE(plockbytes);
    RELEASE(pstm);
    RELEASE(pstg);
    return CreateErrorHelper(
               hresult,
               m_ObjectType);
}


//=--------------------------------------------------------------------------=
// CMSMQMessage::GetStreamedObject
//=--------------------------------------------------------------------------=
// Produce streamed object from binary message body
//
// Parameters:
//    pvarBody - [out] pointer to object
//
// Output:
//
// Notes:
//  Object must implement IPersistStream
//

#if 0 // Not yet implemented
HRESULT CMSMQMessage::GetStreamedObject(VARIANT FAR* pvarBody)
{
	
	HRESULT hresult = NOERROR;

    IUnknown *punk = NULL;
    IDispatch *pdisp = NULL;
    IStream *pstm = NULL;
    IPersistStream *ppersstm = NULL;
    

    ASSERT(pvarBody, L"bad variant.");
    VariantClear(pvarBody);

    // Attempt to load from an in-memory stream
    if (m_hMem) {
      ASSERT(m_hMem == GlobalHandle(m_pbBody), L"bad handle.");
      IfFailGo(GetStreamOfBody(m_cbBody, m_pbBody, &pstm));

      // load
      IfFailGo(OleLoadFromStream(pstm,
                                 IID_IPersistStream,
                                 (void **)&ppersstm));
      //
      // Supports IDispatch? if not, return IUnknown
      //
      IfFailGo(ppersstm->QueryInterface(IID_IUnknown,
                                        (LPVOID *)&punk));
      RELEASE(ppersstm);
      hresult = punk->QueryInterface(IID_IDispatch,
                                     (LPVOID *)&pdisp);
      if (SUCCEEDED(hresult)) {
        //
        // Setup returned object
        //
        V_VT(pvarBody) = VT_DISPATCH;
        pvarBody->pdispVal = pdisp;
        ADDREF(pvarBody->pdispVal);   // ownership transfers
      }
      else {
        //
        // return IUnknown interface
        //
        V_VT(pvarBody) = VT_UNKNOWN;
        pvarBody->punkVal = punk;
        ADDREF(pvarBody->punkVal);   // ownership transfers
      }
    }
    else {
      V_VT(pvarBody) = VT_ERROR;
    }

    // fall through...

Error:
    RELEASE(punk);
    RELEASE(pstm);
    RELEASE(pdisp);
    RELEASE(ppersstm);

    return CreateErrorHelper(hresult, m_ObjectType);
}
#endif // 0

//=--------------------------------------------------------------------------=
// CMSMQMessage::GetStoredObject
//=--------------------------------------------------------------------------=
// Produce stored object from binary message body
//
// Parameters:
//    pvarBody - [out] pointer to object
//
// Output:
//
// Notes:
//  Object must implement IPersistStorage
//
#if 0 // not yet implemented
HRESULT CMSMQMessage::GetStoredObject(VARIANT FAR* pvarBody)
{
    IUnknown *punk = NULL;
    IDispatch *pdisp = NULL;
    IStorage *pstg = NULL;
    IPersistStorage *ppersstg = NULL;
    HRESULT hresult = NOERROR;
#if DEBUG
    LPOLESTR pwszGuid;
#endif // DEBUG
    ASSERT(pvarBody, L"bad variant.");
    VariantClear(pvarBody);

    // Attempt to load from an in-memory storage
    if (m_hMem) {
      ASSERT(m_hMem == GlobalHandle(m_pbBody), L"bad handle.");
      //
      // try to load as a storage
      //
      IfFailGo(GetStorageOfBody(m_cbBody, m_pbBody, &pstg));
#if 0
      //
      // UNDONE: for some reason this doesn't work -- i.e. the returned
      //  object doesn't support IDispatch...
      //
      IfFailGo(OleLoad(pstg,
                       IID_IPersistStorage,
                       NULL,  //Points to the client site for the object
                       (void **)&ppersstg));
#else
      CLSID clsid;
      IfFailGo(ReadClassStg(pstg, &clsid))
      IfFailGo(CoCreateInstance(
                 clsid,
                 NULL,
                 CLSCTX_SERVER,
                 IID_IPersistStorage,
                 (LPVOID *)&ppersstg));
      IfFailGo(ppersstg->Load(pstg));
#endif // 0
#if DEBUG
      // get clsid
      STATSTG statstg;

      IfFailGo(pstg->Stat(&statstg, STATFLAG_NONAME));
      StringFromCLSID(statstg.clsid, &pwszGuid);
#endif // DEBUG
#if 0
      //
      // Now setup returned object
      //
      V_VT(pvarBody) = VT_DISPATCH;
      pvarBody->pdispVal = pdisp;
      ADDREF(pvarBody->pdispVal);   // ownership transfers
#else
      //
      // Supports IDispatch? if not, return IUnknown
      //
      IfFailGo(ppersstg->QueryInterface(IID_IUnknown,
                                        (LPVOID *)&punk));
      hresult = punk->QueryInterface(IID_IDispatch,
                                     (LPVOID *)&pdisp);
      if (SUCCEEDED(hresult)) {
        //
        // Setup returned object
        //
        V_VT(pvarBody) = VT_DISPATCH;
        pvarBody->pdispVal = pdisp;
        ADDREF(pvarBody->pdispVal);   // ownership transfers
      }
      else {
        //
        // return IUnknown interface
        //
        V_VT(pvarBody) = VT_UNKNOWN;
        pvarBody->punkVal = punk;
        ADDREF(pvarBody->punkVal);   // ownership transfers
      }
#endif // 0
    }
    else {
      V_VT(pvarBody) = VT_ERROR;
    }

    // fall through...

Error:
    RELEASE(punk);
    RELEASE(pstg);
    RELEASE(ppersstg);
    RELEASE(pdisp);
    return CreateErrorHelper(hresult, m_ObjectTyp

⌨️ 快捷键说明

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