📄 ndrtypes.cpp
字号:
return hr; } HRESULT NdrEnum::unmarshal1 (NdrUnmarshalStream* pStrm) { HRESULT hr = pStrm->align (alignment ()); if (FAILED (hr)) return hr; if (m_bV1Enum) { // New-style 32-bit enum... DWORD val; hr = pStrm->extract (sizeof (val), &val, true); if (FAILED (hr)) return hr; *m_pValue = (DUMMY) val; } else { // Old-style 16-bit enum... short val; hr = pStrm->extract (sizeof (val), &val, true); if (FAILED (hr)) return hr; *m_pValue = (DUMMY) val; } return hr; }////////////////////////////////////////////////////////////////////////////void* NdrType::operator new (size_t n, NdrTypeFactory* pf) { return pf->allocate (n); }////////////////////////////////////////////////////////////////////////////void NdrType::operator delete (void*) {}////////////////////////////////////////////////////////////////////////////NdrTypeFactory::NdrTypeFactory (int hint) { TRACE_CALL; size_t nBytes = hint * TYPESIZE; m_begin = new char [nBytes]; m_curr = m_begin; m_end = m_begin + nBytes; }////////////////////////////////////////////////////////////////////////////NdrTypeFactory::~NdrTypeFactory () { TRACE_CALL; if (m_begin) delete [] m_begin; }////////////////////////////////////////////////////////////////////////////void* NdrTypeFactory::allocate (size_t nb) { COM_ASSERT((m_end - m_curr) > (int) nb); if ((m_end - m_curr) < (int) nb) return 0; void* pv = m_curr; m_curr += nb; return pv; }////////////////////////////////////////////////////////////////////////////// NdrType base-class default implementations of the marshaling// functions. Derived classes should put their main marshaling code in// marshal1() (and correspondingly, their main unmarshaling code in// unmarshal1()), the default implementations of marshal() and// unmarshal() simply call 1 then 2. This potential for splitting the// marshaling into 2 stages allows the marshaling of [unique] pointers// inside structures and arrays to work correctly.//HRESULT NdrType::marshal2 (NdrMarshalStream*) { return S_OK; }HRESULT NdrType::unmarshal2 (NdrUnmarshalStream*) { return S_OK; }HRESULT NdrType::marshal (NdrMarshalStream* pStrm) { HRESULT hr = marshal1 (pStrm); if (FAILED (hr)) return hr; return marshal2 (pStrm); }HRESULT NdrType::unmarshal (NdrUnmarshalStream* pStrm) { HRESULT hr = unmarshal1 (pStrm); if (FAILED (hr)) return hr; return unmarshal2 (pStrm); }void NdrType::arraySizeSet (int n) { m_ndrtypes.arraySize = n; }int NdrType::arraySizeGet () { return m_ndrtypes.arraySize; }////////////////////////////////////////////////////////////////////////////size_t NdrStruct::size (NdrUnmarshalStream* pStrm) { TRACE_CALL; size_t nSize = 0; for (size_t n=0; n < m_nMembers; ++n) nSize += m_pMemberInfo [n].pType->size (pStrm); return nSize; }////////////////////////////////////////////////////////////////////////////// NdrStruct::alignment -- the alignment of a structure is the largest// alignment() value of any of its members...//size_t NdrStruct::alignment () const { TRACE_CALL; size_t nAlign = 0; for (size_t i=0; i < m_nMembers; ++i) { size_t n = m_pMemberInfo [i].pType->alignment (); if (n > nAlign) nAlign = n; } return nAlign; }////////////////////////////////////////////////////////////////////////////// NdrStruct::init -- record structure info, including optionally the// index of the structure-member which holds the [size_is] value for// dynamically-sized structure members. This index will be -1 if there// is no dynamically-sized member in the structure.//void NdrStruct::init (size_t n, const NdrMemberInfo members [], int nsize_is) { TRACE_CALL; m_nMembers = n; m_pMemberInfo = new NdrMemberInfo [n]; for (size_t i=0; i < n; ++i) m_pMemberInfo[i] = members[i]; m_nSizeIs = nsize_is; m_pInstance = 0; }////////////////////////////////////////////////////////////////////////////NdrStruct::~NdrStruct () { if (m_pMemberInfo) delete [] m_pMemberInfo; }////////////////////////////////////////////////////////////////////////////// NdrStruct::bind -- bind to a new instance of the type we// represent. We defer the binding of individual structure members// until the last minute...//void NdrStruct::bind (void* pv) { TRACE_CALL; m_pInstance = pv; }////////////////////////////////////////////////////////////////////////////// NdrConfStruct::confElemResize -- calculate the actual value of the// 'size_is' attribute, given its index in the m_nSizeIs member, and// resize the appropriate structure-member to this value. This// method should *NOT* be called if this index is negative, i.e. there// is no size_is attribute...//size_t NdrConfStruct::confElemResize () { COM_ASSERT (m_nSizeIs >= 0); char* addr = (char*) m_pInstance; // find the value of the 'conformance' variable NdrMemberInfo* pConf = &m_pMemberInfo [m_nSizeIs]; pConf->pType->bind (addr + pConf->nOffset); unsigned long nArrayCount = pConf->pType->value (); // resize the varying-length element so it knows to marshal // the right number of items (if applicable)... m_pMemberInfo [m_nMembers - 1].pType->resize (nArrayCount); return nArrayCount; }////////////////////////////////////////////////////////////////////////////// NdrStruct::marshal1 -- call marshal1() for all the members...//HRESULT NdrStruct::marshal1 (NdrMarshalStream* pStrm) { TRACE_CALL; // find the start of the current instance char* addr = (char*) m_pInstance; // align pStrm->align (alignment ()); // call marshal1() for each element for (size_t n=0; n < m_nMembers; ++n) { m_pMemberInfo [n].pType->bind (addr + m_pMemberInfo [n].nOffset); HRESULT hr = m_pMemberInfo [n].pType->marshal1 (pStrm); if (FAILED (hr)) return hr; } return S_OK; }////////////////////////////////////////////////////////////////////////////// NdrStruct::marshal2 -- call marshal2() for all the members. Any// members which have a valid 'size_is' indicator must be resized to// the value nominated in their member-descriptor. This information is// provided for all struct and cstruct members which have a [size_is]// attribute present...//HRESULT NdrStruct::marshal2 (NdrMarshalStream* pStrm) { TRACE_CALL; char* addr = (char*) m_pInstance; // call marshal2() for each element for (size_t n=0; n < m_nMembers; ++n) { NdrMemberInfo& member = m_pMemberInfo [n]; // Does it have a [size_is] attribute... if (member.nSizeIs >= 0) { NdrMemberInfo& sizeMem = m_pMemberInfo [member.nSizeIs]; sizeMem.pType->bind (addr + sizeMem.nOffset); size_t size_is = sizeMem.pType->value (); member.pType->resize (size_is); } // Now marshal the actual member... member.pType->bind (addr + member.nOffset); HRESULT hr = member.pType->marshal2 (pStrm); if (FAILED (hr)) return hr; } return S_OK; }////////////////////////////////////////////////////////////////////////////// NdrStruct::unmarshal1 -- unmarshal all the structure members one by// one from the stream. The repeated operation mirrors the marshaling// side... //HRESULT NdrStruct::unmarshal1 (NdrUnmarshalStream* pStrm) { TRACE_CALL; S_DEBUG (LOG_DCOM, "U1:struct @ " << m_pInstance); // find the start of the current instance char* addr = (char*) m_pInstance; // align pStrm->align (alignment ()); // call unmarshal1() for each element for (size_t n=0; n < m_nMembers; ++n) { m_pMemberInfo [n].pType->bind (addr + m_pMemberInfo [n].nOffset); HRESULT hr = m_pMemberInfo [n].pType->unmarshal1 (pStrm); if (FAILED (hr)) return hr; } return S_OK; }////////////////////////////////////////////////////////////////////////////// NdrStruct::unmarshal2 -- call unmarshal2() for all the members...//HRESULT NdrStruct::unmarshal2 (NdrUnmarshalStream* pStrm) { TRACE_CALL; char* addr = (char*) m_pInstance; S_DEBUG (LOG_DCOM, "U2:struct @ " << m_pInstance); // call unmarshal2() for each element for (size_t n=0; n < m_nMembers; ++n) { m_pMemberInfo [n].pType->bind (addr + m_pMemberInfo [n].nOffset); HRESULT hr = m_pMemberInfo [n].pType->unmarshal2 (pStrm); if (FAILED (hr)) return hr; } return S_OK; }////////////////////////////////////////////////////////////////////////////// NdrConfStruct::marshal1 -- marshal all the structure members one by// one into the stream, preceded by the array length. On entry, this// descriptor is bound to the start of the structure...//HRESULT NdrConfStruct::marshal1 (NdrMarshalStream* pStrm) { TRACE_CALL; // Always calculate dynamic size for conf-structs... unsigned long nArrayCount = confElemResize (); // marshal array-count first, as 4-byte value (unsigned long) pStrm->align (4); HRESULT hr = pStrm->insert (4, &nArrayCount, true); if (FAILED (hr)) return hr; S_DEBUG (LOG_DCOM, "M1:cstruct:size_is=" << nArrayCount); // marshal structure member-wise return NdrStruct::marshal1 (pStrm); }////////////////////////////////////////////////////////////////////////////// NdrConfStruct::unmarshal1 -- unmarshal all the structure members one// by one from the stream, preceded by the array-length of the last// member. The m_pInstance pointer is pointing to the start of space// allocated to hold the structure itself...//HRESULT NdrConfStruct::unmarshal1 (NdrUnmarshalStream* pStrm) { TRACE_CALL; S_DEBUG (LOG_DCOM, "U1:cstruct"); // unmarshal structure member-wise return NdrStruct::unmarshal1 (pStrm); }////////////////////////////////////////////////////////////////////////////// NdrConfStruct::size -- during unmarshaling, extract the required// size of this structure (accounting for the variable-length array)// from the unmarshaling stream, and modify the descriptor for that// array to hold the discovered size.//size_t NdrConfStruct::size (NdrUnmarshalStream* pStrm) { TRACE_CALL; // unmarshal array-count first, as 4-byte value (unsigned long) unsigned long nArrayCount; pStrm->align (4); HRESULT hr = pStrm->extract (4, &nArrayCount, true); if (FAILED (hr)) return hr; S_DEBUG (LOG_DCOM, "SZ:cstruct:size_is=" << nArrayCount); // resize the varying-length element so it knows to unmarshal // the right number of items (if applicable)... m_pMemberInfo [m_nMembers - 1].pType->resize (nArrayCount); // Now add up the size of all elements... size_t nSize = 0; for (size_t n=0; n < m_nMembers; ++n) nSize += m_pMemberInfo [n].pType->size (pStrm); return nSize; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -