123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474 |
- /////////////////////////////////////////////////////////////////////////////
- // AGCEventData.cpp : Implementation of CAGCEventData
- //
- #include "pch.h"
- #include "AGCEventData.h"
- #include <..\TCAtl\SimpleStream.h>
- #include <..\TCAtl\TCNullStreamImpl.h>
- /////////////////////////////////////////////////////////////////////////////
- // CAGCEventData
- /////////////////////////////////////////////////////////////////////////////
- // Construction / Destruction
- /////////////////////////////////////////////////////////////////////////////
- // Attributes
- void CAGCEventData::GetVarData(BSTR* pbstrContext, BSTR* pbstrSubject,
- CAGCEventData::XProperties* pProperties) const
- {
- // Get a pointer to the beginning of the variable data block
- assert(m_pbData && m_cbData >= sizeof(XData));
- XData* pData = reinterpret_cast<XData*>(m_pbData);
- BYTE* pbData = reinterpret_cast<BYTE*>(pData + 1);
- // Read the context string
- pbData += CreateBSTRFromData_LPSTR(pbData, pbstrContext);
- // Read the subject name
- pbData += CreateBSTRFromData_LPWSTR(pbData, pbstrSubject);
- // Add each association to the specified property map
- CComBSTR bstrKey;
- CComVariant varItem;
- for (long cArgTriplets = GetArgCount(); cArgTriplets; --cArgTriplets)
- {
- // Read the argument name
- pbData += CreateBSTRFromData_LPSTR(pbData, &bstrKey);
- // Read the argument value
- pbData += CreateVARIANTFromData(pbData, varItem);
- // Add the association to the property map
- pProperties->insert(XProperties::value_type(bstrKey, varItem));
- // Free the BSTR
- bstrKey.Empty();
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- // Implementation
- /////////////////////////////////////////////////////////////////////////////
- // Useful macro for implementing size calculations of variant types
- //
- #define VT_SIZE(vt, type) \
- case vt: \
- va_arg(argptr, type); \
- cbTotal += sizeof(type); \
- break;
- /////////////////////////////////////////////////////////////////////////////
- //
- UINT CAGCEventData::ComputeVariableDataSize(LPCSTR pszContext,
- LPCOLESTR pszSubject, long cArgTriplets, va_list argptr)
- {
- // Start with the string length of the specified context string, if any
- UINT cbTotal = pszContext ? strlen(pszContext) : 0;
- cbTotal += sizeof(cbTotal);
- // Next is the string length of the specified subject string, if any
- cbTotal += pszSubject ? (wcslen(pszSubject) * sizeof(WCHAR)) : 0;
- cbTotal += sizeof(cbTotal);
- // Iterate through the argument triplets
- for (long i = 0; i < cArgTriplets; ++i)
- {
- // Get the argument name
- LPCSTR pszArgName = va_arg(argptr, LPCSTR);
- assert(!IsBadStringPtrA(pszArgName, UINT(-1)));
- // Get the argument name length
- UINT cchName = strlen(pszArgName);
- cbTotal += sizeof(cchName) + cchName;
- // Get the argument variant type and value
- VARTYPE vt = va_arg(argptr, VARTYPE);
- cbTotal += sizeof(vt);
- switch (vt)
- {
- VT_SIZE(VT_BOOL , VARIANT_BOOL)
- VT_SIZE(VT_I1 , CHAR)
- VT_SIZE(VT_I2 , SHORT)
- VT_SIZE(VT_I4 , LONG)
- VT_SIZE(VT_UI1 , BYTE)
- VT_SIZE(VT_UI2 , USHORT)
- VT_SIZE(VT_ERROR , SCODE)
- case VT_R4:
- {
- // (...) pushes a float argument onto the stack as a double
- va_arg(argptr, DOUBLE);
- cbTotal += sizeof(float);
- break;
- }
- VT_SIZE(VT_R8 , DOUBLE)
- VT_SIZE(VT_DECIMAL, DECIMAL)
- VT_SIZE(VT_CY , CY)
- VT_SIZE(VT_DATE , DATE)
- case VT_BSTR:
- {
- BSTR bstr = va_arg(argptr, BSTR);
- UINT cb = bstr ? SysStringByteLen(bstr) : 0;
- cbTotal += sizeof(cb) + cb;
- break;
- }
- case VT_UNKNOWN:
- case VT_DISPATCH:
- {
- // Object *must* support IPersistStream(Init)
- IUnknown* punk = va_arg(argptr, IUnknown*);
- IPersistStreamPtr sppstm(punk);
- if (punk && NULL == sppstm)
- ZSucceeded(punk->QueryInterface(IID_IPersistStreamInit,
- (void**)&sppstm));
- // Create a Null stream for calculating persisent size
- TCNullStreamImpl stm;
- // 'Persist' the object to the stream to determine its size
- OleSaveToStream(sppstm, &stm);
- // Get the object's persistent size
- ULARGE_INTEGER cbSize;
- LARGE_INTEGER dlibMove = {0, 0};
- ZSucceeded(stm.Seek(dlibMove, STREAM_SEEK_CUR, &cbSize));
- assert(0 == cbSize.HighPart);
- cbTotal += sizeof(cbSize.LowPart) + cbSize.LowPart;
- break;
- }
- case VT_VARIANT:
- // TODO: Could recurse here to support VT_VARIANT
- ZError("Unsupported Variant Type");
- break;
- case VT_LPSTR:
- {
- LPCSTR psz = va_arg(argptr, LPCSTR);
- UINT cch = psz ? strlen(psz) : 0;
- cbTotal += sizeof(cch) + cch;
- break;
- }
- case VT_LPWSTR:
- {
- LPCWSTR psz = va_arg(argptr, LPCWSTR);
- UINT cch = psz ? wcslen(psz) : 0;
- cbTotal += sizeof(cch) + cch * sizeof(WCHAR);
- break;
- }
- default:
- ZError("Unsupported Variant Type");
- }
- }
- // Return the total size
- return cbTotal;
- }
- /////////////////////////////////////////////////////////////////////////////
- // Useful macros for implementing data copying
- //
- #define COPY_DATA(pData, cb) \
- { \
- int _cb = (cb); \
- if (_cb) \
- { \
- assert(cbData >= _cb); \
- CopyMemory(pbData, pData, _cb); \
- cbData -= _cb; \
- pbData += _cb; \
- } \
- }
- #define COPY_VAR(var) \
- COPY_DATA(&var, sizeof(var))
- #define VT_COPY(vt, type) \
- case vt: \
- { \
- type var = va_arg(argptr, type); \
- COPY_VAR(var); \
- break; \
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- void CAGCEventData::CopyVariableData(LPCSTR pszContext, LPCOLESTR pszSubject,
- long cArgTriplets, va_list argptr)
- {
- // Get initial pointers and byte count
- UINT cbData = m_cbData - sizeof(XData);
- BYTE* pbData = m_pbData + sizeof(XData);
- // Start with the specified context string, if any
- UINT cb = pszContext ? strlen(pszContext) : 0;
- COPY_VAR(cb);
- COPY_DATA(pszContext, cb);
- // Next is the specified subject string, if any
- cb = pszSubject ? (wcslen(pszSubject) * sizeof(WCHAR)) : 0;
- COPY_VAR(cb);
- COPY_DATA(pszSubject, cb);
- // Iterate through the argument triplets
- for (long i = 0; i < cArgTriplets; ++i)
- {
- // Get the argument name
- LPCSTR pszArgName = va_arg(argptr, LPCSTR);
- cb = strlen(pszArgName);
- COPY_VAR(cb);
- COPY_DATA(pszArgName, cb);
- // Get the argument variant type and value
- VARTYPE vt = va_arg(argptr, VARTYPE);
- COPY_VAR(vt);
- switch (vt)
- {
- VT_COPY(VT_BOOL , VARIANT_BOOL)
- VT_COPY(VT_I1 , CHAR)
- VT_COPY(VT_I2 , SHORT)
- VT_COPY(VT_I4 , LONG)
- VT_COPY(VT_UI1 , BYTE)
- VT_COPY(VT_UI2 , USHORT)
- VT_COPY(VT_ERROR , SCODE)
- case VT_R4:
- {
- // (...) pushes a float argument onto the stack as a double
- float var = va_arg(argptr, DOUBLE);
- COPY_VAR(var);
- break;
- }
- VT_COPY(VT_R8 , DOUBLE)
- VT_COPY(VT_DECIMAL, DECIMAL)
- VT_COPY(VT_CY , CY)
- VT_COPY(VT_DATE , DATE)
- case VT_BSTR:
- {
- BSTR bstr = va_arg(argptr, BSTR);
- cb = bstr ? SysStringByteLen(bstr) : 0;
- COPY_VAR(cb);
- COPY_DATA(bstr, cb);
- break;
- }
- case VT_UNKNOWN:
- case VT_DISPATCH:
- {
- // Object *must* support IPersistStream(Init)
- IUnknown* punk = va_arg(argptr, IUnknown*);
- IPersistStreamPtr sppstm(punk);
- if (punk && NULL == sppstm)
- ZSucceeded(punk->QueryInterface(IID_IPersistStreamInit,
- (void**)&sppstm));
- // Create a simple stream on the memory block
- TCSimpleStream stm;
- stm.Init(cbData - sizeof(ULONG), pbData + sizeof(ULONG));
- // Persist the object to the memory block stream
- OleSaveToStream(sppstm, &stm);
- // Get the object's persistent size
- ULARGE_INTEGER cbSize;
- LARGE_INTEGER dlibMove = {0, 0};
- ZSucceeded(stm.Seek(dlibMove, STREAM_SEEK_CUR, &cbSize));
- assert(0 == cbSize.HighPart);
- // Save the size of the persistent object
- COPY_VAR(cbSize.LowPart);
- // Just skip past bytes already written as stream
- cbData -= cbSize.LowPart;
- pbData += cbSize.LowPart;
- break;
- }
- case VT_VARIANT:
- // TODO: Could recurse here to support VT_VARIANT
- ZError("Unsupported Variant Type");
- break;
- case VT_LPSTR:
- {
- LPCSTR psz = va_arg(argptr, LPCSTR);
- cb = psz ? strlen(psz) : 0;
- COPY_VAR(cb);
- COPY_DATA(psz, cb);
- break;
- }
- case VT_LPWSTR:
- {
- LPCWSTR psz = va_arg(argptr, LPCWSTR);
- cb = psz ? (wcslen(psz) * sizeof(WCHAR)) : 0;
- COPY_VAR(cb);
- COPY_DATA(psz, cb);
- break;
- }
- default:
- ZError("Unsupported Variant Type");
- }
- }
- }
- /////////////////////////////////////////////////////////////////////////////
- // Useful macro for implementing VARIANT creations of simple variant types.
- //
- #define VT_CREATE(_vt, type) \
- case VT##_vt: \
- V##_vt(&var) = *reinterpret_cast<type*>(pbData); \
- cbData = sizeof(type); \
- break;
- /////////////////////////////////////////////////////////////////////////////
- //
- // Return Value: The number of bytes consumed from the input buffer. The
- // caller should increment its pointer by this many bytes.
- //
- UINT CAGCEventData::CreateVARIANTFromData(BYTE* pbData, CComVariant& var)
- {
- // Clear the specified VARIANT
- ZSucceeded(var.Clear());
- // Get the VARTYPE from the specified buffer
- V_VT(&var) = *reinterpret_cast<VARTYPE*>(pbData);
- pbData += sizeof(V_VT(&var));
- // Switch on the VARTYPE
- UINT cbData = 0;
- switch (V_VT(&var))
- {
- VT_CREATE(_BOOL , VARIANT_BOOL)
- VT_CREATE(_I1 , CHAR)
- VT_CREATE(_I2 , SHORT)
- VT_CREATE(_I4 , LONG)
- VT_CREATE(_UI1 , BYTE)
- VT_CREATE(_UI2 , USHORT)
- VT_CREATE(_ERROR , SCODE)
- VT_CREATE(_R4 , FLOAT)
- VT_CREATE(_R8 , DOUBLE)
- VT_CREATE(_DECIMAL, DECIMAL)
- VT_CREATE(_CY , CY)
- VT_CREATE(_DATE , DATE)
- case VT_BSTR:
- cbData = CreateBSTRFromData(pbData, &V_BSTR(&var));
- break;
- case VT_UNKNOWN:
- cbData = CreateObjectFromData(pbData, IID_IUnknown,
- (void**)&V_UNKNOWN(&var));
- break;
- case VT_DISPATCH:
- cbData = CreateObjectFromData(pbData, IID_IDispatch,
- (void**)&V_DISPATCH(&var));
- break;
- case VT_VARIANT:
- // TODO: Could recurse here to support VT_VARIANT
- ZError("Unsupported Variant Type");
- break;
- case VT_LPSTR:
- cbData = CreateBSTRFromData_LPSTR(pbData, &V_BSTR(&var));
- V_VT(&var) = VT_BSTR;
- break;
- case VT_LPWSTR:
- cbData = CreateBSTRFromData_LPWSTR(pbData, &V_BSTR(&var));
- V_VT(&var) = VT_BSTR;
- break;
- default:
- ZError("Unsupported Variant Type");
- }
- // Return the number of bytes consumed from the buffer
- return sizeof(V_VT(&var)) + cbData;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // Return Value: The number of bytes consumed from the input buffer. The
- // caller should increment its pointer by this many bytes.
- //
- UINT CAGCEventData::CreateBSTRFromData(BYTE* pbData, BSTR* pbstr)
- {
- // Get the size of the following persistence block
- UINT cbData = *reinterpret_cast<UINT*>(pbData);
- pbData += sizeof(cbData);
- // Create the BSTR from the persistence block
- *pbstr = SysAllocStringByteLen(reinterpret_cast<LPCSTR>(pbData), cbData);
- assert(*pbstr);
- // Return the number of bytes consumed
- return sizeof(cbData) + cbData;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // Return Value: The number of bytes consumed from the input buffer. The
- // caller should increment its pointer by this many bytes.
- //
- UINT CAGCEventData::CreateBSTRFromData_LPSTR(BYTE* pbData, BSTR* pbstr)
- {
- // Get the size of the following persistence block
- UINT cch = *reinterpret_cast<UINT*>(pbData);
- pbData += sizeof(cch);
- // Convert the ANSI persistence block to UNICODE
- LPOLESTR pwsz = (LPOLESTR)_alloca((cch + 1) * sizeof(OLECHAR));
- MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
- reinterpret_cast<LPCSTR>(pbData), cch, pwsz, cch + 1);
- // Create the BSTR from the converted persistence block
- *pbstr = SysAllocStringLen(pwsz, cch);
- assert(*pbstr);
- // Return the number of bytes consumed
- return sizeof(cch) + cch;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // Return Value: The number of bytes consumed from the input buffer. The
- // caller should increment its pointer by this many bytes.
- //
- UINT CAGCEventData::CreateBSTRFromData_LPWSTR(BYTE* pbData, BSTR* pbstr)
- {
- // Get the size of the following persistence block
- UINT cb = *reinterpret_cast<UINT*>(pbData);
- pbData += sizeof(cb);
- // Create the BSTR from the persistence block
- UINT cch = cb / sizeof(OLECHAR);
- *pbstr = SysAllocStringLen(reinterpret_cast<LPOLESTR>(pbData), cch);
- assert(*pbstr);
- // Return the number of bytes consumed
- return sizeof(cb) + cb;
- }
- /////////////////////////////////////////////////////////////////////////////
- //
- // Return Value: The number of bytes consumed from the input buffer. The
- // caller should increment its pointer by this many bytes.
- //
- UINT CAGCEventData::CreateObjectFromData(BYTE* pbData, REFIID riid,
- void** ppvUnk)
- {
- // Get the size of the following persistence block
- UINT cbData = *reinterpret_cast<UINT*>(pbData);
- pbData += sizeof(cbData);
- // Create a simple stream on the persistence block
- TCSimpleStream stm;
- stm.Init(cbData, pbData);
- // Create the object from the data
- ZSucceeded(OleLoadFromStream(&stm, riid, ppvUnk));
- // Return the number of bytes consumed
- return sizeof(cbData) + cbData;
- }
|