📄 ndrtypes.cpp
字号:
{ // unmarshal the interface memStrm.locationSet (0); hr = CoUnmarshalInterface (static_cast<IStream*> (&memStrm), m_iid, (void**) m_pPointer); } } } return hr; }////////////////////////////////////////////////////////////////////////////// NdrBSTR::marshal1/2 -- according to the MS headers (and IDL) the wire// format of a BSTR is FLAGGED_WORD_BLOB structure -- a flags-word,// the array-length, then the array of wide-chars. However, looking at// real marshaled packets on the network shows another structure where// the characters 'User' precede the string! Which is right???// Obviously, the info snooped off the network.//// The format is 'User' followed by the string as a CV-array of wide// chars... //HRESULT NdrBSTR::marshal1 (NdrMarshalStream* pStrm) { // align buffer correctly first HRESULT hr = pStrm->align (sizeof (long)); if (FAILED (hr)) return hr; // now insert the chars 'User' one at a time char userText [] = "User"; return pStrm->insert (4, userText, false); }HRESULT NdrBSTR::marshal2 (NdrMarshalStream* pStrm) { long a, b, c; BSTR bstr = *m_pBstr; if (bstr) { b = ::SysStringByteLen (bstr); a = c = (b/2); } else { a = c = 0; b = -1; } // align first HRESULT hr = pStrm->align (sizeof (long)); if (FAILED (hr)) return hr; // now insert the length words pStrm->insert (sizeof (long), &a, true); pStrm->insert (sizeof (long), &b, true); hr = pStrm->insert (sizeof (long), &c, true); if (FAILED (hr)) return hr; // Now insert the text -- we assume it is wide-character data, // unless the user-configurable policy parameter has been set, // which means we should treat BSTRs as byte arrays... if (vxdcomBSTRPolicy == 0) { // treat BSTR as array of OLECHARs, marshaling each one // individually so byte-ordering is preserved... for (long n=0; n < a; ++n) hr = pStrm->insert (sizeof (short), &bstr[n], true); } else hr = pStrm->insert (b, bstr, false); return hr; }////////////////////////////////////////////////////////////////////////////// NdrBSTR::unmarshal1 -- simply reverses the above process...//HRESULT NdrBSTR::unmarshal1 (NdrUnmarshalStream* pStrm) { char user [8]; /// align first HRESULT hr = pStrm->align (sizeof (long)); if (FAILED (hr)) return hr; for (int n=0; n < 4; ++n) pStrm->extract (sizeof (char), &user [n], false); user [4] = 0; if (strcmp (user, "User") != 0) return E_UNEXPECTED; return S_OK; }HRESULT NdrBSTR::unmarshal2 (NdrUnmarshalStream* pStrm) { /// align first HRESULT hr = pStrm->align (sizeof (long)); if (FAILED (hr)) return hr; // now unmarshal length fields long a, b, c; pStrm->extract (sizeof (long), &a, true); pStrm->extract (sizeof (long), &b, true); hr = pStrm->extract (sizeof (long), &c, true); // 'a' should == 'c' and 'b' is twice 'a', unless the BSTR is // NULL, in which case 'a' and 'c' are zero and 'b' is -1 (or // 0xFFFFFFFF if you prefer)... BSTR bstr = 0; if (a) { COM_ASSERT(a == c); COM_ASSERT(b == 2*a); // Get a string - remember, we are working in terms of OLECHARs // unless the system was built with the 'marshal as chars' policy bstr = SysAllocStringLen (0, a); // Read the string - if we are treating BSTRs as array of // OLECHAR then we need to marshal each wide-char individually // to retain byte-ordering... if (vxdcomBSTRPolicy == 0) { for (long n=0; n < a; ++n) hr = pStrm->extract (sizeof (short), &bstr [n], true); } else hr = pStrm->extract (b, bstr, false); // Terminate the string... bstr [a] = 0; } *m_pBstr = bstr; return hr; }////////////////////////////////////////////////////////////////////////////// Strings are marshaled as conformant varying arrays, with both the// max and the length being strlen() + 1 effectively...// HRESULT NdrWString::marshal1 (NdrMarshalStream* pStrm) { pStrm->align (4); WCHAR* str = m_pString; m_len = vxcom_wcslen (str) + 1; m_max = m_len; m_offset = 0; pStrm->insert (sizeof (m_max), &m_max, true); pStrm->insert (sizeof (m_offset), &m_offset, true); HRESULT hr = pStrm->insert (sizeof (m_len), &m_len, true); if (FAILED (hr)) return hr; for (ULONG i=0; i < m_len; ++i) hr = pStrm->insert (sizeof(WCHAR), &str [i], true); return hr; }////////////////////////////////////////////////////////////////////////////HRESULT NdrWString::unmarshal1 (NdrUnmarshalStream* pStrm) { HRESULT hr = S_OK; S_DEBUG (LOG_DCOM, "U1:wstring"); WCHAR* wsz = m_pString + m_offset; for (ULONG i=0; i < m_len; ++i) hr = pStrm->extract (sizeof(WCHAR), &wsz [i], true); return hr; }////////////////////////////////////////////////////////////////////////////size_t NdrWString::size (NdrUnmarshalStream* pStrm) { pStrm->align (4); pStrm->extract (sizeof (m_max), &m_max, true); pStrm->extract (sizeof (m_offset), &m_offset, true); HRESULT hr = pStrm->extract (sizeof (m_len), &m_len, true); if (FAILED (hr)) return 0; size_t nBytes = m_max * sizeof(WCHAR); S_DEBUG (LOG_DCOM, "SZ:wstring:len=" << nBytes); return nBytes; } ////////////////////////////////////////////////////////////////////////////HRESULT NdrCString::marshal1 (NdrMarshalStream* pStrm) { pStrm->align (4); m_len = strlen (m_pString) + 1; m_max = m_len; m_offset = 0; pStrm->insert (sizeof (m_max), &m_max, true); pStrm->insert (sizeof (m_offset), &m_offset, true); pStrm->insert (sizeof (m_len), &m_len, true); return pStrm->insert (m_len, m_pString + m_offset, false); }////////////////////////////////////////////////////////////////////////////HRESULT NdrCString::unmarshal1 (NdrUnmarshalStream* pStrm) { return pStrm->extract (m_len, m_pString + m_offset, false); }////////////////////////////////////////////////////////////////////////////size_t NdrCString::size (NdrUnmarshalStream* pStrm) { pStrm->align (4); pStrm->extract (sizeof (m_max), &m_max, true); pStrm->extract (sizeof (m_offset), &m_offset, true); HRESULT hr = pStrm->extract (sizeof (m_len), &m_len, true); if (FAILED (hr)) return 0; return m_max; } ////////////////////////////////////////////////////////////////////////////// NdrPointer::resize -- no sense in resizing the pointer, but as it// may be pointing to an array or something, we simply pass it on...//void NdrPointer::resize (size_t n) { m_pointeeType->resize (n); }////////////////////////////////////////////////////////////////////////////// NdrPointer::marshal1 -- first-stage of marshaling a pointer. If its// a [unique] pointer, just deal with the pointer-referent, deferring// the pointee until marshal2() time...//HRESULT NdrPointer::marshal1 (NdrMarshalStream* pStrm) { // Find actual pointer value from binding... void* referent = *m_pPtr; if (! m_refptr) { // Its a [unique] ptr... pStrm->align (4); HRESULT hr = pStrm->insert (sizeof (long), &referent, true); if (FAILED (hr)) return hr; } return S_OK; }HRESULT NdrPointer::marshal2 (NdrMarshalStream* pStrm) { // Find actual pointer value from binding... void* referent = *m_pPtr; // Nothing to do if its NULL... if (referent == 0) return S_OK; // Either a [unique] ptr with non-NULL referent, or a [ref] // pointer, so go ahead and marshal the pointee... m_pointeeType->bind (referent); return m_pointeeType->marshal (pStrm); }////////////////////////////////////////////////////////////////////////////// NdrPointer::unmarshal1/2 -- when unmarshaling pointers, we need to// keep the pointer-value (actually, the 'referent' which is not a// true pointer, just an indicator of NULL-ness or otherwise)// somewhere safe. Formerly, it was kept in m_referent, but since this// may be re-used inside, for example, an array of pointers, by many// pointer instances, we now keep the referent in '*m_pPtr' between// calls to unmarshal1() and unmarshal2()...//HRESULT NdrPointer::unmarshal1 (NdrUnmarshalStream* pStrm) { // Now decide how to dereference this pointer. If its a [ref] // pointer then, by definition, it must point to something (its a // pass-by-reference)... if (m_refptr) { // Its a [ref] pointer, so if we are unmarshaling in the stub, // then we need to mark it with some arbitrary non-NULL // value. If its in the proxy-unmshl phase, it will have a // real (non-NULL) value, so we can leave it as-is... if (pStrm->phaseGet () == NdrPhase::STUB_UNMSHL) *m_pPtr = (void*) 0xDEADBEEF; S_DEBUG (LOG_DCOM, "U1:[ref]ptr:referent=" << (*m_pPtr)); } else { // Its a [unique] pointer, so we need to allocate memory if // unmarshaling return-values in the proxy, pStrm->align (4); void* referent; HRESULT hr = pStrm->extract (sizeof (long), &referent, true); if (FAILED (hr)) return hr; // Save referent-value (although its not a true pointer in this // context, yet) in the pointer variable... *m_pPtr = referent; S_DEBUG (LOG_DCOM, "U1:[unique]ptr:referent=" << referent); } return S_OK; }HRESULT NdrPointer::unmarshal2 (NdrUnmarshalStream* pStrm) { // On entry, the referent-value is either NULL, or some // meaningless, but non-NULL, value. If its NULL, there is no // pointee to unmarshal... void* referent = *m_pPtr; if (referent == 0) return S_OK; // Non-NULL referent, so we can unmarshal the pointee. First, we // ask the pointee for its size, this forces it to read the // unmarshaling stream if its a conformant type... size_t objSize = m_pointeeType->size (pStrm); // If its a [unique] pointer, we may need to allocate some memory // for the pointer to point to. However, if we're in the // stub-unmarshaling phase we can borrow the stream memory. Either // way, we need to get the referent pointing to some real memory if (pStrm->phaseGet () == NdrPhase::STUB_UNMSHL) { //referent = pStrm->curr (); referent = pStrm->stubAlloc (objSize); if (m_refptr) {S_DEBUG (LOG_DCOM, "U2:[ref]ptr:value=" << referent << " size=" << objSize);} else {S_DEBUG (LOG_DCOM, "U2:[unique]ptr:value=" << referent << " size=" << objSize);} } else { // If its a [ref] ptr, then it must (since we're in the proxy // unmarshal phase) be pointing at something real, so we // simply dereference it to get to the pointee. If its a // [unique] pointer, in the proxy-unmarshal phase, we need to // allocate memory to hold the pointee... if (m_refptr) { S_DEBUG (LOG_DCOM, "U2:[ref]ptr:value=" << referent << " size=" << objSize); } else { referent = CoTaskMemAlloc (objSize); if (! referent) return E_OUTOFMEMORY; S_DEBUG (LOG_DCOM, "U2:[unique]ptr:value=" << referent << " size=" << objSize); } } // Set the value of the pointer-variable... *m_pPtr = referent; // Now unmarshal the pointee, at last... m_pointeeType->bind (referent); return m_pointeeType->unmarshal (pStrm); }NDRTYPES::NDRTYPES (int hint) { m_pFactory = new NdrTypeFactory (hint); }NDRTYPES::~NDRTYPES () { if (m_pFactory) delete m_pFactory; }NdrTypeDesc NDRTYPES::byte_t () { COM_ASSERT(m_pFactory); NdrSimple<byte>* td = new (m_pFactory) NdrSimple<byte> (*this); return td; }NdrTypeDesc NDRTYPES::short_t () {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -