📄 ndrtypes.cpp
字号:
COM_ASSERT(m_pFactory); NdrSimple<short> *td = new (m_pFactory) NdrSimple<short> (*this); return td; }NdrTypeDesc NDRTYPES::long_t () { COM_ASSERT(m_pFactory); NdrSimple<long> *td = new (m_pFactory) NdrSimple<long> (*this); return td; }NdrTypeDesc NDRTYPES::enum_t () { COM_ASSERT(m_pFactory); NdrEnum *td = new (m_pFactory) NdrEnum (*this); td->init (false); return td; }NdrTypeDesc NDRTYPES::v1enum_t () { COM_ASSERT(m_pFactory); NdrEnum *td = new (m_pFactory) NdrEnum (*this); td->init (true); return td; }NdrTypeDesc NDRTYPES::hyper_t () { COM_ASSERT(m_pFactory); NdrSimple<hyper> *td = new (m_pFactory) NdrSimple<hyper> (*this); return td; }NdrTypeDesc NDRTYPES::float_t () { COM_ASSERT(m_pFactory); NdrSimple<float> *td = new (m_pFactory) NdrSimple<float> (*this); return td; }NdrTypeDesc NDRTYPES::double_t () { COM_ASSERT(m_pFactory); NdrSimple<double> *td = new (m_pFactory) NdrSimple<double> (*this); return td; }NdrTypeDesc NDRTYPES::bstr_t () { COM_ASSERT(m_pFactory); NdrBSTR *td = new (m_pFactory) NdrBSTR (*this); return td; }NdrTypeDesc NDRTYPES::struct_t (int nelems, const NdrMemberInfo m[], int nSizeIs) { COM_ASSERT(m_pFactory); NdrStruct *td = new (m_pFactory) NdrStruct (*this); td->init (nelems, m, nSizeIs); return td; }NdrTypeDesc NDRTYPES::cstruct_t (int nelems, const NdrMemberInfo m[], int nSizeIs) { COM_ASSERT(m_pFactory); NdrConfStruct *td = new (m_pFactory) NdrConfStruct (*this); td->init (nelems, m, nSizeIs); return td; }NdrTypeDesc NDRTYPES::array_t (const NdrTypeDesc& eltype, size_t elsz, size_t nelems) { COM_ASSERT(m_pFactory); NdrArray *td = new (m_pFactory) NdrArray (*this); td->init (eltype, elsz, nelems, 0, nelems); return td; }NdrTypeDesc NDRTYPES::carray_t (const NdrTypeDesc& eltype, size_t elsz, size_t nelems) { COM_ASSERT(m_pFactory); NdrConfArray *td = new (m_pFactory) NdrConfArray (*this); td->init (eltype, elsz, nelems, 0, nelems); return td; }NdrTypeDesc NDRTYPES::cvarray_t (const NdrTypeDesc& eltype, size_t elsz, size_t nelems, size_t nmax) { COM_ASSERT(m_pFactory); NdrConfVarArray *td = new (m_pFactory) NdrConfVarArray (*this); td->NdrArray::init (eltype, elsz, nmax, 0, nelems); return td; }NdrTypeDesc NDRTYPES::interfaceptr_t (const IID& riid) { COM_ASSERT(m_pFactory); NdrInterface *td = new (m_pFactory) NdrInterface (*this); td->init (riid); return td; }NdrTypeDesc NDRTYPES::variant_t () { COM_ASSERT(m_pFactory); NdrVariant *td = new (m_pFactory) NdrVariant (*this); return td; }NdrTypeDesc NDRTYPES::wstring_t () { COM_ASSERT(m_pFactory); NdrWString *td = new (m_pFactory) NdrWString (*this); return td; }NdrTypeDesc NDRTYPES::cstring_t () { COM_ASSERT(m_pFactory); NdrCString *td = new (m_pFactory) NdrCString (*this); return td; }NdrTypeDesc NDRTYPES::pointer_t (const NdrTypeDesc& pt) { COM_ASSERT(m_pFactory); NdrPointer *td = new (m_pFactory) NdrPointer (*this, false); td->init (pt); return td; }NdrTypeDesc NDRTYPES::refptr_t (const NdrTypeDesc& pt) { COM_ASSERT(m_pFactory); NdrPointer *td = new (m_pFactory) NdrPointer (*this, true); td->init (pt); return td; }////////////////////////////////////////////////////////////////////////////// widlMarshal -- simplified WIDL runtime marshaling routine, takes// the stream, the address of the top-level variable to be marshaled,// and the type-descriptor, and binds the descriptor to the variable// before invoking its marshal() method...//HRESULT widlMarshal (void const* pv, NdrMarshalStream* pms, const NdrTypeDesc& t) { NdrTypeDesc& td = const_cast<NdrTypeDesc&> (t); td->bind (const_cast<void*> (pv)); HRESULT hr = td->marshal1 (pms); if (FAILED (hr)) return hr; return td->marshal2 (pms); }HRESULT widlUnmarshal (void* pv, NdrUnmarshalStream* pus, const NdrTypeDesc& t) { NdrTypeDesc& td = const_cast<NdrTypeDesc&> (t); td->bind (pv); HRESULT hr = td->unmarshal1 (pus); if (FAILED (hr)) return hr; return td->unmarshal2 (pus); }////////////////////////////////////////////////////////////////////////////// VARIANT marshaling support. The VARIANT structure, in true MS// fashion, is wire-marshaled differently from its in-memory// representation. To see the wire-representation, look at OAIDL.IDL,// which contains the full details. Basically, the start of the// wireVARIANT structure is as follows:-//// DWORD clSize; /* wire buffer length in units of hyper */// DWORD rpcReserved; /* for future use */// USHORT vt;// USHORT wReserved1;// USHORT wReserved2;// USHORT wReserved3;//// ...followed by the usual union, with 'vt' as the discriminator,// and a slightly restricted set of types within the union. In the// first release, we will only cope with simple VARIANTs, and none of// the pointer or BYREF vartypes. This means effectively the intrinsic// types plus VT_UNKNOWN and VT_BSTR.//HRESULT NdrVariant::marshal1 (NdrMarshalStream* pStrm) { char user [] = "User"; // Start with the header ("User" + padding)... pStrm->align (4); return pStrm->insert (4, user, false); }HRESULT NdrVariant::marshal2 (NdrMarshalStream* pStrm) { // First, make sure its a VT we can cope with... switch (m_pVariant->vt & VT_TYPEMASK) { case VT_EMPTY: case VT_NULL: case VT_UI1: case VT_I2: case VT_I4: case VT_R4: case VT_R8: case VT_CY: case VT_DATE: case VT_BSTR: case VT_ERROR: case VT_BOOL: case VT_UNKNOWN: break; default: S_ERR (LOG_DCOM, "Unsupported VARTYPE:" << hex << m_pVariant->vt << endl); return DISP_E_BADVARTYPE; } // The total length of required buffer space must be calculated, // in units of hyper. The size of the header is constant, and its // only the union part that is variable. Without counting [unique] // pointers, the max extra size is sizeof(double) (i.e. 8 bytes) // except for the interface-ptr and BSTR cases. To simplify this // process, we create a 2nd marshaling stream and marshal the // entire structure into there first, (including the leading // DWORD, so we can get alignment right). We then use its size to // calculate the rounded-up packet size, and copy the whole lot // into the real stream... NdrMarshalStream s2 (pStrm->phaseGet (), pStrm-> drep ()); DWORD rpcReserved=0; USHORT wReserved=0; // Stuff a dummy clSize value in, to allow for correct alignment // within the VARIANT packet... ULONG clSizeDummy=0; s2.insert (sizeof(ULONG), &clSizeDummy, true); // Now the post-clSize contents... s2.insert (sizeof(rpcReserved), &rpcReserved, true); s2.insert (sizeof(USHORT), &m_pVariant->vt, true); s2.insert (sizeof(USHORT), &wReserved, true); s2.insert (sizeof(USHORT), &wReserved, true); HRESULT hr = s2.insert (sizeof(USHORT), &wReserved, true); if (FAILED (hr)) return hr; // Now the union part -- first the discriminator, then the // body. We don't marshal the discriminator (as there's no body) // if its VT_EMPTY or VT_NULL, nice one MS! // Marshal discriminator ULONG discrim; if (V_ISARRAY(m_pVariant)) { discrim = VT_ARRAY; } else { discrim = m_pVariant->vt & VT_TYPEMASK; } s2.insert (sizeof (ULONG), &discrim, true); NDRTYPES ndrtypes; // Marshal union-body? if (V_ISARRAY(m_pVariant)) { NdrSafearray ndrSafearray (ndrtypes); ndrSafearray.bind (m_pVariant); hr = ndrSafearray.marshal (&s2); } else { // This is a simple type. switch (m_pVariant->vt & VT_TYPEMASK) { case VT_EMPTY: case VT_NULL: break; case VT_UI1: hr = s2.insert (sizeof (byte), &V_UI1(m_pVariant), false); s2.addEndPadding (8); break; case VT_I2: hr = s2.insert (sizeof (short), &V_I2(m_pVariant), true); s2.addEndPadding (8); break; case VT_I4: hr = s2.insert (sizeof (long), &V_I4(m_pVariant), true); break; case VT_R4: hr = s2.insert (sizeof (float), &V_R4(m_pVariant), true); break; case VT_R8: hr = marshalDouble (&s2, &V_R8(m_pVariant)); break; case VT_CY: s2.align (sizeof (CY)); hr = s2.insert (sizeof (CY), &V_CY(m_pVariant) , true); break; case VT_DATE: s2.align (sizeof (DATE)); hr = s2.insert (sizeof (DATE), &V_DATE(m_pVariant), true); break; case VT_ERROR: hr = s2.insert (sizeof (SCODE), &V_ERROR(m_pVariant), true); break; case VT_BOOL: hr = s2.insert (sizeof (VARIANT_BOOL), &V_BOOL(m_pVariant), true); s2.addEndPadding (8); break; case VT_BSTR: { // We marshal the BSTR pointer referent, then the value itself... s2.insert (sizeof(ULONG), &V_BSTR(m_pVariant), true); if (V_BSTR(m_pVariant)) { NdrBSTR ndrBSTR (ndrtypes); ndrBSTR.bind (&V_BSTR(m_pVariant)); hr = ndrBSTR.marshal2 (&s2); } s2.addEndPadding (8); } break; case VT_UNKNOWN: { // Need to add the length of the marshaled interface pointer // packet... NdrInterface ndrItf (ndrtypes); ndrItf.init (IID_IUnknown); ndrItf.bind (&V_UNKNOWN(m_pVariant)); hr = ndrItf.marshal (&s2); } break; default: hr = DISP_E_BADVARTYPE; } } // Check marshaling results... if (FAILED (hr)) return hr; // Calculate the size including the leading 'clSize' word, which // will be a multiple of sizeof(hyper) since we aligned the stream // already... ULONG clSize = (s2.size () + sizeof(hyper) - 1) / sizeof(hyper); // Now insert the actual clSize value into the main stream... pStrm->align (sizeof (hyper)); pStrm->insert (sizeof (ULONG), &clSize, true); // Transfer any padding that have been added. pStrm->addEndPadding (s2.getEndPadding ()); // Now copy s2 (except for its first 4 bytes) to the main stream... return pStrm->insert (s2.size () - sizeof(ULONG), s2.begin () + sizeof(ULONG), false); }////////////////////////////////////////////////////////////////////////////// NdrVariant::size -- determine the actual wire-size, and return the// required memory size (which is sizeof(VARIANT) since we don't// support indirected types yet). This advances the stream position// over all the run-in data, leaving only the actual data in the// stream. Thus, when it gets unmarshaled, it can be over-written in// place, like all other data types...//size_t NdrVariant::size (NdrUnmarshalStream* pStrm) { S_DEBUG (LOG_DCOM, "SZ:variant"); return sizeof (VARIANT); }////////////////////////////////////////////////////////////////////////////// NdrVariant::unmarshal1 -- unmarshal the "User" string, and check it// is correct...//HRESULT NdrVariant::unmarshal1 (NdrUnmarshalStream* pStrm) { HRESULT hr = pStrm->align (4); if (FAILED (hr)) return hr; char user[5]; // "User" string hr = pStrm->extract (4, user, false); user[4]=0; S_DEBUG (LOG_DCOM, "U1:variant"); i
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -