📄 ndrtypes.cpp
字号:
////////////////////////////////////////////////////////////////////////////void NdrArray::init ( const NdrTypeDesc& elementType, size_t elemSize, size_t max, size_t offset, size_t len ) { TRACE_CALL; m_pElementType = elementType; m_nElementSize = elemSize; m_arraySize = len; m_offset = offset; m_max = max; m_ptr = 0; }////////////////////////////////////////////////////////////////////////////size_t NdrArray::size (NdrUnmarshalStream*) { return m_arraySize * m_nElementSize; }////////////////////////////////////////////////////////////////////////////size_t NdrArray::alignment () const { return m_pElementType->alignment (); }////////////////////////////////////////////////////////////////////////////// NdrArray::bind -- bind to an actual array of whatever type we are// dealing with...//void NdrArray::bind (void* pv) { TRACE_CALL; // Bind to instance address... m_ptr = pv; }////////////////////////////////////////////////////////////////////////////// NdrArray::marshal1 -- marshal the array into the stream...//HRESULT NdrArray::marshal1 (NdrMarshalStream* pStrm) { TRACE_CALL; // locate start of array in user memory char* pmem = (char*) m_ptr; // align pStrm->align (alignment ()); // call marshal1() for individual elements for (size_t n=0; n < m_arraySize; ++n) { m_pElementType->bind (pmem); HRESULT hr = m_pElementType->marshal1 (pStrm); if (FAILED (hr)) return hr; pmem += m_nElementSize; } return S_OK; }////////////////////////////////////////////////////////////////////////////// NdrArray::marshal2 -- call marshal2() for each element//HRESULT NdrArray::marshal2 (NdrMarshalStream* pStrm) { TRACE_CALL; // locate start of array in user memory char* pmem = (char*) m_ptr; // align pStrm->align (alignment ()); // call marshal2() for individual elements for (size_t n=0; n < m_arraySize; ++n) { m_pElementType->bind (pmem); HRESULT hr = m_pElementType->marshal2 (pStrm); if (FAILED (hr)) return hr; pmem += m_nElementSize; } return S_OK; }////////////////////////////////////////////////////////////////////////////// NdrArray::unmarshal1 -- unmarshal the fixed-size array from the// stream, assuming that the memory to hold the array already// exists...//HRESULT NdrArray::unmarshal1 (NdrUnmarshalStream* pStrm) { TRACE_CALL; // locate the start of the array char* pmem = (char*) m_ptr; S_DEBUG (LOG_DCOM, "U1:array"); // align pStrm->align (alignment ()); // call unmarshal1() for elements one at a time for (size_t n=0; n < m_arraySize; ++n) { m_pElementType->bind (pmem); HRESULT hr = m_pElementType->unmarshal1 (pStrm); if (FAILED (hr)) return hr; pmem += m_nElementSize; } return S_OK; }////////////////////////////////////////////////////////////////////////////// NdrArray::unmarshal2 -- call unmarshal2() for each element...//HRESULT NdrArray::unmarshal2 (NdrUnmarshalStream* pStrm) { TRACE_CALL; // locate the start of the array char* pmem = (char*) m_ptr; S_DEBUG (LOG_DCOM, "U2:array"); // align pStrm->align (alignment ()); // call unmarshal2() for elements one at a time for (size_t n=0; n < m_arraySize; ++n) { m_pElementType->bind (pmem); HRESULT hr = m_pElementType->unmarshal2 (pStrm); if (FAILED (hr)) return hr; pmem += m_nElementSize; } return S_OK; }////////////////////////////////////////////////////////////////////////////size_t NdrConfArray::size (NdrUnmarshalStream* pStrm) { // unmarshal array-count first, as 4-byte value (unsigned long) unsigned long nElements; pStrm->align (4); HRESULT hr = pStrm->extract (4, &nElements, true); if (FAILED (hr)) return hr; S_DEBUG (LOG_DCOM, "SZ:carray:size_is=" << nElements); // In NDR rules for arrays, 'conformance' value as found here does // not have to be emitted to a variable - the argument that indicates // the length will be marshaled separately. So, all we do is set // the size of the array to be unmarshaled, and treat it as 'fixed // length' from then on... m_arraySize = nElements; // Return total size of array... return m_arraySize * m_nElementSize; }////////////////////////////////////////////////////////////////////////////// NdrConfArray::marshal1 -- marshal the array into the stream. On// entry, the descriptor is bound to the start of the array...//HRESULT NdrConfArray::marshal1 (NdrMarshalStream* pStrm) { TRACE_CALL; // marshal array-count first, as 4-byte value (unsigned long) unsigned long nElements = m_arraySize; pStrm->align (4); HRESULT hr = pStrm->insert (4, &nElements, true); if (FAILED (hr)) return hr; // Defer to base-class... return NdrArray::marshal1 (pStrm); }////////////////////////////////////////////////////////////////////////////// NdrConfArray::unmarshal1 -- unmarshal the array from the stream...//HRESULT NdrConfArray::unmarshal1 (NdrUnmarshalStream* pStrm) { TRACE_CALL; S_DEBUG (LOG_DCOM, "U1:carray"); // treat as a normal array now... return NdrArray::unmarshal1 (pStrm); }////////////////////////////////////////////////////////////////////////////// NdrConfVarArray::size -- returns size of memory needed to hold// unmarshaled array. It unmarshals the 'max' count, then the offset// (which should always be zero), then defers to the base class// (NdrConfArray) to unmarshal the actual transmitted size. This is// the value we return, since this is the amount of memory we would// need to allocate...//size_t NdrConfVarArray::size (NdrUnmarshalStream* pStrm) { // unmarshal array-max and offset first, as 4-byte values // (unsigned long)... pStrm->align (4); pStrm->extract (4, &m_max, true); HRESULT hr = pStrm->extract (4, &m_offset, true); if (FAILED (hr)) return hr; // Return transmitted size of array... return NdrConfArray::size (pStrm); }////////////////////////////////////////////////////////////////////////////// NdrConfVarArray::marshal1 -- marshal the array into the stream. On// entry, the descriptor is bound to the start of the array...//HRESULT NdrConfVarArray::marshal1 (NdrMarshalStream* pStrm) { TRACE_CALL; // marshal array-max, and zero-offset first, as 4-byte values // (unsigned long)... pStrm->align (4); pStrm->insert (4, &m_max, true); HRESULT hr = pStrm->insert (4, &m_offset, true); if (FAILED (hr)) return hr; // Defer to base-class to marshal the actual runtime size of the // array, plus the array contents... return NdrConfArray::marshal1 (pStrm); }////////////////////////////////////////////////////////////////////////////// NdrInterface::bind -- bind to an instance of an interface// pointer. The address in 'pv' is always the address of the// pointer-variable itself.void NdrInterface::bind (void* pv) { TRACE_CALL; m_pPointer = (IUnknown**) pv; }////////////////////////////////////////////////////////////////////////////// NdrInterface::marshal1 -- marshal the interface-pointer, it goes// into a MInterfacePointer conformant structure before being sent// over the wire...//HRESULT NdrInterface::marshal1 (NdrMarshalStream* pStrm) { TRACE_CALL; // Get hold of the interface ptr... IUnknown* punk = * (IUnknown**) m_pPointer; // We need to marshal a 'pointer referent' first... pStrm->align (4); HRESULT hr = pStrm->insert (sizeof (long), &punk, true); return hr; }HRESULT NdrInterface::marshal2 (NdrMarshalStream* pStrm) { HRESULT hr = S_OK; IUnknown* punk = * (IUnknown**) m_pPointer; // If non-NULL pointer, we must marshal pointer/OBJREF... if (punk) { // Use a 'memory stream' to marshal the interface into VxRWMemStream* pMemStrm = new VxRWMemStream; IStream* pIStream=0; // QI for IStream, this gets us one reference... hr = pMemStrm->QueryInterface (IID_IStream, (void**) &pIStream); if (FAILED (hr)) return hr; // marshal the interface-ptr hr = CoMarshalInterface (pIStream, m_iid, punk, 0, 0, 0); if (SUCCEEDED (hr)) { // okay we got it - now align the stream and put the // marshaling packet into there, in the shape of a // MInterfacePointer structure, i.e. conformance-value // (length), then ulCntData, then abData[] containing the // actual packet... ULONG ulCntData = pMemStrm->size (); pStrm->insert (sizeof (ulCntData), &ulCntData, true); pStrm->insert (sizeof (ulCntData), &ulCntData, true); hr = pStrm->insert (ulCntData, pMemStrm->begin (), false); } pMemStrm->Release (); } return hr; }////////////////////////////////////////////////////////////////////////////// NdrInterface::unmarshal -- see marshal() method for details of// formatting of a marshaled interface pointer...// A cosutom marsh routine is required so that unmarshal2 can be used by// the SAFEARRAY routines.//HRESULT NdrInterface::unmarshal (NdrUnmarshalStream* pStrm) { HRESULT hr = unmarshal1 (pStrm); // Check to see if the ptr is NULL and stop if it is, if (hr == S_FALSE) { return S_OK; } if (FAILED (hr)) return hr; return unmarshal2 (pStrm); }////////////////////////////////////////////////////////////////////////////// NdrInterface::unmarshal1 -- see marshal() method for details of// formatting of a marshaled interface pointer...//HRESULT NdrInterface::unmarshal1 (NdrUnmarshalStream* pStrm) { TRACE_CALL; // align the buffer before we begin HRESULT hr = pStrm->align (4); // unmarshal the conformance-value (length), then the conf-array // member 'ulCntData' (which will be the same) and then the array // of bytes... // need to extract 'ptr referent' first... ULONG pp; hr = pStrm->extract (sizeof (pp), &pp, true); // If ptr is NULL, thats okay, but we have nothing else to do so // return a dummy code to unmarshal to indicate this. if (pp == 0) return S_FALSE; return hr; } HRESULT NdrInterface::unmarshal2 (NdrUnmarshalStream* pStrm) { TRACE_CALL; HRESULT hr; // Use a 'memory stream' to hold the marshaling packet, and make // sure we don't try to delete it from the stack! VxRWMemStream memStrm; memStrm.AddRef (); // Now extract the actual MInterfacePointer... ULONG length; hr = pStrm->extract (sizeof (length), &length, true); if (SUCCEEDED (hr)) { ULONG ulCntData; hr = pStrm->extract (sizeof (ulCntData), &ulCntData, true); if (SUCCEEDED (hr)) { COM_ASSERT(length == ulCntData); // get the bytes from the unmarshaling stream into the // memory-stream, ready for CoUnmarshalInterface()... memStrm.insert (pStrm->curr (), ulCntData); hr = pStrm->extract (memStrm.locationGet (), 0, false); if (SUCCEEDED (hr))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -