mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1220 lines
34 KiB
1220 lines
34 KiB
//=--------------------------------------------------------------------------=
|
|
// wbclsser.h
|
|
//=--------------------------------------------------------------------------=
|
|
// Copyright 1995 Microsoft Corporation. All Rights Reserved.
|
|
//
|
|
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
// PARTICULAR PURPOSE.
|
|
//=--------------------------------------------------------------------------=
|
|
//
|
|
// API for WebClass Designer Serialization
|
|
//
|
|
// adolfoc 7/29/97
|
|
// Renamed WCS_NODE_TYPE_URL to WCS_NODE_TYPE_PAGE,
|
|
// added WCS_NODE_TYPE_URL with value 3,
|
|
// changed URL tag to Page
|
|
//
|
|
#ifndef _WBCLSSER_H_
|
|
|
|
#include "csfdebug.h"
|
|
#include "convman_tlb.h"
|
|
|
|
// Designer State Flags
|
|
#define RUNSTATE_COMPILED 0x00000000
|
|
#define RUNSTATE_F5 0x00000001
|
|
|
|
#define DISPID_OBJECT_PROPERTY_START 0x00000500
|
|
|
|
// Serialization Versions
|
|
// 0.0 Beta1
|
|
// 0.1 PreBeta2 - WebItems must be sorted on load
|
|
// 0.2 PreBeta2 - Added Optimize member var to WebItems
|
|
// 0.3 PreBeta2 - WebEvents are now sorted on load too
|
|
// 0.4 PreBeta2 -
|
|
// 0.5 PreBeta2 - Tagattributes added anonymous tag number
|
|
// 0.6 <skipped>
|
|
// 0.7 PreRC1 - Added URLInName to design time state
|
|
// 0.8 PreRC1 - Fixed bug in WebItem and event sorting algorithm. Now we need
|
|
// to fixup old projects with bug whose WebItems and events are not
|
|
// serialized in alphabetical order.
|
|
|
|
// structure of WebClass on disk
|
|
const DWORD dwExpectedVerMajor = 0;
|
|
const DWORD dwExpectedVerMinor = 8;
|
|
|
|
class CRunWebItemState;
|
|
class CRunEventState;
|
|
|
|
class CStateBase
|
|
{
|
|
public:
|
|
CStateBase() {}
|
|
~CStateBase() {}
|
|
|
|
public:
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// inline ReadStrings(IStream *pStream, ULONG acbStrings[],
|
|
// BSTR *apbstrStrings[], int cStrings)
|
|
//
|
|
//
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
inline ReadStrings(IStream *pStream, ULONG acbStrings[],
|
|
BSTR *apbstrStrings[], int cStrings)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
ULONG cbRead = 0;
|
|
char *pszReadBuf = NULL;
|
|
ULONG cbLongest = 0;
|
|
int i = 0;
|
|
|
|
while (i < cStrings)
|
|
{
|
|
if (acbStrings[i] > cbLongest)
|
|
{
|
|
cbLongest = acbStrings[i];
|
|
}
|
|
i++;
|
|
}
|
|
if (0 != cbLongest)
|
|
{
|
|
pszReadBuf = new char[cbLongest + sizeof(WCHAR)];
|
|
CSF_CHECK(NULL != pszReadBuf, E_OUTOFMEMORY, CSF_TRACE_EXTERNAL_ERRORS);
|
|
}
|
|
i = 0;
|
|
while (i < cStrings)
|
|
{
|
|
if (0 == acbStrings[i])
|
|
{
|
|
*(apbstrStrings[i]) = NULL;
|
|
}
|
|
else
|
|
{
|
|
hr = pStream->Read(pszReadBuf, acbStrings[i], &cbRead);
|
|
CSF_CHECK(hr == S_OK, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(cbRead == acbStrings[i], STG_E_DOCFILECORRUPT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
*((WCHAR *)&pszReadBuf[acbStrings[i]]) = L'\0';
|
|
|
|
*(apbstrStrings[i]) = ::SysAllocString((WCHAR *)pszReadBuf);
|
|
CSF_CHECK(*(apbstrStrings[i]) != NULL, E_OUTOFMEMORY, CSF_TRACE_EXTERNAL_ERRORS);
|
|
}
|
|
i++;
|
|
}
|
|
|
|
CLEANUP:
|
|
if (NULL != pszReadBuf)
|
|
{
|
|
delete [] pszReadBuf;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// inline WriteStrings(IStream *pStream, ULONG acbStrings[],
|
|
// BSTR *apbstrStrings[], int cStrings)
|
|
//
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
inline WriteStrings(IStream *pStream, ULONG acbStrings[],
|
|
BSTR abstrStrings[], int cStrings)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
ULONG cbWritten = 0;
|
|
int i = 0;
|
|
|
|
while (i < cStrings)
|
|
{
|
|
if (NULL != abstrStrings[i])
|
|
{
|
|
hr = pStream->Write(abstrStrings[i], acbStrings[i], &cbWritten);
|
|
CSF_CHECK(hr == S_OK, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(cbWritten == acbStrings[i], STG_E_WRITEFAULT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
}
|
|
i++;
|
|
}
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
}
|
|
|
|
};
|
|
|
|
class CRunWebClassState : public CStateBase
|
|
{
|
|
public:
|
|
CRunWebClassState()
|
|
{
|
|
m_dwVerMajor = dwExpectedVerMajor;
|
|
m_dwVerMinor = dwExpectedVerMinor;
|
|
m_bstrName = NULL; // Kill
|
|
m_bstrProgID = NULL; // Runtime only
|
|
m_StateManagementType = wcNoState;
|
|
m_bstrASPName = NULL;
|
|
m_bstrAppendedParams = NULL;
|
|
m_bstrStartupItem = NULL;
|
|
m_DIID_WebClass = GUID_NULL;
|
|
m_DIID_WebClassEvents = GUID_NULL;
|
|
m_dwTICookie = 0;
|
|
m_dwFlags = 0;
|
|
m_rgWebItemsState = 0;
|
|
m_dwWebItemCount = 0;
|
|
}
|
|
|
|
~CRunWebClassState()
|
|
{
|
|
if(m_bstrName != NULL)
|
|
::SysFreeString(m_bstrName);
|
|
|
|
if(m_bstrProgID != NULL)
|
|
::SysFreeString(m_bstrProgID);
|
|
|
|
if(m_bstrASPName != NULL)
|
|
::SysFreeString(m_bstrASPName);
|
|
|
|
if(m_bstrAppendedParams != NULL)
|
|
::SysFreeString(m_bstrAppendedParams);
|
|
|
|
if(m_bstrStartupItem != NULL)
|
|
::SysFreeString(m_bstrStartupItem);
|
|
}
|
|
|
|
public:
|
|
DWORD m_dwVerMajor; // major version number
|
|
DWORD m_dwVerMinor; // minor version number
|
|
BSTR m_bstrName; // WebClass name
|
|
BSTR m_bstrProgID; // WebClass progid
|
|
StateManagement m_StateManagementType; // state management type
|
|
BSTR m_bstrASPName; // name of ASP file
|
|
IID m_DIID_WebClass; // IID of WebClass' main IDispatch
|
|
IID m_DIID_WebClassEvents; // IID of WebClass' events IDispatch
|
|
DWORD m_dwTICookie; // typeinfo cookie
|
|
BSTR m_bstrAppendedParams; // URL state
|
|
BSTR m_bstrStartupItem; // f5 statup Item
|
|
DWORD m_dwFlags;
|
|
CRunWebItemState* m_rgWebItemsState;
|
|
DWORD m_dwWebItemCount; // runtime node types
|
|
|
|
public:
|
|
HRESULT Load(LPSTREAM pStm)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
ULONG cbRead = 0;
|
|
ULONG acbStrings[5];
|
|
BSTR *apbstrStrings[5];
|
|
|
|
// read structure from stream
|
|
|
|
hr = pStm->Read(this, sizeof(CRunWebClassState), &cbRead);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(sizeof(CRunWebClassState) == cbRead, STG_E_DOCFILECORRUPT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
// TODO: need error codes for version incompatibility, handle backlevel formats etc.
|
|
|
|
// CSF_CHECK(dwExpectedVerMajor == m_dwVerMajor, STG_E_OLDFORMAT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
// CSF_CHECK(dwExpectedVerMinor == m_dwVerMinor, STG_E_OLDFORMAT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
// read string lengths from stream
|
|
|
|
hr = pStm->Read(acbStrings, sizeof(acbStrings), &cbRead);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(sizeof(acbStrings) == cbRead, STG_E_DOCFILECORRUPT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
// set up array of string pointer addresses
|
|
|
|
apbstrStrings[0] = &(m_bstrName);
|
|
apbstrStrings[1] = &(m_bstrProgID);
|
|
apbstrStrings[2] = &(m_bstrASPName);
|
|
apbstrStrings[3] = &(m_bstrAppendedParams);
|
|
apbstrStrings[4] = &(m_bstrStartupItem);
|
|
|
|
// read strings from stream
|
|
|
|
hr = ReadStrings(pStm, acbStrings, apbstrStrings,
|
|
(sizeof(acbStrings) / sizeof(acbStrings[0])) );
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
}
|
|
|
|
HRESULT Save(LPSTREAM pStm)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
ULONG cbWritten = 0;
|
|
ULONG acbStrings[5];
|
|
::ZeroMemory(acbStrings, sizeof(acbStrings));
|
|
BSTR abstrStrings[5];
|
|
|
|
// write WebClass structure to stream
|
|
|
|
hr = pStm->Write(this, sizeof(CRunWebClassState), &cbWritten);
|
|
CSF_CHECK(hr == S_OK, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(cbWritten == sizeof(CRunWebClassState), STG_E_WRITEFAULT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
// get lengths of strings and write them to stream
|
|
|
|
if (NULL != m_bstrName)
|
|
{
|
|
acbStrings[0] = ::SysStringByteLen(m_bstrName);
|
|
}
|
|
if (NULL != m_bstrProgID)
|
|
{
|
|
acbStrings[1] = ::SysStringByteLen(m_bstrProgID);
|
|
}
|
|
if (NULL != m_bstrASPName)
|
|
{
|
|
acbStrings[2] = ::SysStringByteLen(m_bstrASPName);
|
|
}
|
|
if (NULL != m_bstrAppendedParams)
|
|
{
|
|
acbStrings[3] = ::SysStringByteLen(m_bstrAppendedParams);
|
|
}
|
|
if (NULL != m_bstrStartupItem)
|
|
{
|
|
acbStrings[4] = ::SysStringByteLen(m_bstrStartupItem);
|
|
}
|
|
|
|
hr = pStm->Write(acbStrings, sizeof(acbStrings), &cbWritten);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(cbWritten == sizeof(acbStrings), STG_E_WRITEFAULT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
// set up array of pointers to strings to be written to stream
|
|
|
|
abstrStrings[0] = m_bstrName;
|
|
abstrStrings[1] = m_bstrProgID;
|
|
abstrStrings[2] = m_bstrASPName;
|
|
abstrStrings[3] = m_bstrAppendedParams;
|
|
abstrStrings[4] = m_bstrStartupItem;
|
|
|
|
// write strings to stream
|
|
|
|
hr = WriteStrings(pStm, acbStrings, abstrStrings,
|
|
(sizeof(acbStrings) / sizeof(acbStrings[0])) );
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
}
|
|
};
|
|
|
|
typedef struct tagWCS_NODEHEADER
|
|
{
|
|
BYTE bType; // node type: nested WebClass, URL, events
|
|
} WCS_NODEHEADER;
|
|
|
|
// WCS_DTNODE_TYPE_URL_BOUND_TAG is a special case because WCS_DTNODE.dispid
|
|
// contains the dispid of the referenced URL and WCS_DTNODE.bstrName contains
|
|
// the name of the referenced URL.
|
|
|
|
// structure of node on disk at runtime
|
|
|
|
class CRunWebItemState : protected CStateBase
|
|
{
|
|
public:
|
|
CRunWebItemState()
|
|
{
|
|
m_dwVerMajor = dwExpectedVerMajor;
|
|
m_dwVerMinor = dwExpectedVerMinor;
|
|
m_dispid = -1;
|
|
m_bstrName = NULL;
|
|
m_bstrTemplate = NULL;
|
|
m_bstrToken = NULL;
|
|
m_IID_Events = GUID_NULL;
|
|
m_fParseReplacements = FALSE;
|
|
m_bstrAppendedParams = NULL;
|
|
m_fUsesRelativePath = FALSE;
|
|
m_dwTokenInfo = 0;
|
|
m_dwReserved2 = 0;
|
|
m_dwReserved3 = 0;
|
|
m_rgEvents = 0;
|
|
m_dwEventCount = 0;
|
|
}
|
|
|
|
~CRunWebItemState()
|
|
{
|
|
if(m_bstrName != NULL)
|
|
::SysFreeString(m_bstrName);
|
|
|
|
if(m_bstrTemplate != NULL)
|
|
::SysFreeString(m_bstrTemplate);
|
|
|
|
if(m_bstrToken != NULL)
|
|
::SysFreeString(m_bstrToken);
|
|
|
|
if(m_bstrAppendedParams != NULL)
|
|
::SysFreeString(m_bstrAppendedParams);
|
|
}
|
|
|
|
public:
|
|
HRESULT Load(LPSTREAM pStm)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
ULONG cbRead = 0;
|
|
ULONG acbStrings[4];
|
|
BSTR *apbstrStrings[4];
|
|
int cStrings = 4;
|
|
|
|
// read structure from stream
|
|
|
|
hr = pStm->Read(this, sizeof(CRunWebItemState), &cbRead);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(sizeof(CRunWebItemState) == cbRead, STG_E_DOCFILECORRUPT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
// m_pvData = NULL; // don't take junk pointer value from stream
|
|
|
|
// set up array of string pointer addresses according to node type
|
|
|
|
apbstrStrings[0] = &m_bstrName;
|
|
apbstrStrings[1] = &m_bstrTemplate;
|
|
apbstrStrings[2] = &m_bstrToken;
|
|
apbstrStrings[3] = &m_bstrAppendedParams;
|
|
|
|
// read string lengths from stream
|
|
|
|
hr = pStm->Read(acbStrings, sizeof(acbStrings), &cbRead);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(sizeof(acbStrings) == cbRead, STG_E_DOCFILECORRUPT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
// read strings from stream
|
|
|
|
hr = ReadStrings(pStm, acbStrings, apbstrStrings, cStrings);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_INTERNAL_ERRORS);
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
}
|
|
|
|
HRESULT Save
|
|
(
|
|
LPSTREAM pStm
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
ULONG cbWritten = 0;
|
|
ULONG acbStrings[4];
|
|
::ZeroMemory(acbStrings, sizeof(acbStrings));
|
|
BSTR abstrStrings[4];
|
|
int cStrings = 4;
|
|
|
|
// write node structure to stream
|
|
|
|
hr = pStm->Write(this, sizeof(CRunWebItemState), &cbWritten);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(sizeof(CRunWebItemState) == cbWritten, STG_E_WRITEFAULT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
// set up array of strings to be written to stream and
|
|
// determine how many there will be
|
|
|
|
abstrStrings[0] = m_bstrName;
|
|
if (NULL != m_bstrName)
|
|
{
|
|
acbStrings[0] = ::SysStringByteLen(m_bstrName);
|
|
}
|
|
|
|
abstrStrings[1] = m_bstrTemplate;
|
|
if (NULL != m_bstrTemplate)
|
|
{
|
|
acbStrings[1] = ::SysStringByteLen(m_bstrTemplate);
|
|
}
|
|
abstrStrings[2] = m_bstrToken;
|
|
if (NULL != m_bstrToken)
|
|
{
|
|
acbStrings[2] = ::SysStringByteLen(m_bstrToken);
|
|
}
|
|
abstrStrings[3] = m_bstrAppendedParams;
|
|
if (NULL != m_bstrAppendedParams)
|
|
{
|
|
acbStrings[3] = ::SysStringByteLen(m_bstrAppendedParams);
|
|
}
|
|
|
|
// write string lengths to stream
|
|
|
|
hr = pStm->Write(acbStrings, sizeof(acbStrings), &cbWritten);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(sizeof(acbStrings) == cbWritten, STG_E_WRITEFAULT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
// write strings to stream
|
|
|
|
hr = WriteStrings(pStm, acbStrings, abstrStrings, cStrings);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_INTERNAL_ERRORS);
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
}
|
|
|
|
public:
|
|
DWORD m_dwVerMajor;
|
|
DWORD m_dwVerMinor;
|
|
// common properties
|
|
DISPID m_dispid; // dispid of node
|
|
BSTR m_bstrName; // name of node
|
|
|
|
// url properties
|
|
BSTR m_bstrTemplate; // url's HTML template name
|
|
BSTR m_bstrToken; // url's token for replacement events
|
|
IID m_IID_Events; // IID of url's dynamic events interface
|
|
BOOL m_fParseReplacements; // TRUE=parse replacement recursively
|
|
BSTR m_bstrAppendedParams; // Appended params
|
|
BOOL m_fUsesRelativePath; // Specifies whether the runtime should load
|
|
// templates relative to the ASP's actual path
|
|
|
|
DWORD m_dwTokenInfo;
|
|
DWORD m_dwReserved2;
|
|
DWORD m_dwReserved3;
|
|
CRunEventState* m_rgEvents;
|
|
DWORD m_dwEventCount;
|
|
};
|
|
|
|
// design time node types
|
|
|
|
#define WCS_NODE_TYPE_RESOURCE (BYTE)10
|
|
//#define WCS_DTNODE_TYPE_UNBOUND_TAG (BYTE)12
|
|
//#define WCS_DTNODE_TYPE_NESTED_WEBCLASS (BYTE)15
|
|
|
|
//#define WCS_DTNODE_TYPE_CUSTOM_EVENT (BYTE)11
|
|
//#define WCS_DTNODE_TYPE_URL_BOUND_TAG (BYTE)13
|
|
//#define WCS_DTNODE_TYPE_EVENT_BOUND_TAG (BYTE)14
|
|
|
|
class CRunEventState : public CStateBase
|
|
{
|
|
public:
|
|
enum EventTypes
|
|
{
|
|
typeCustomEvent,
|
|
typeURLBoundTag,
|
|
typeEventBoundTag,
|
|
typeUnboundTag,
|
|
};
|
|
|
|
CRunEventState()
|
|
{
|
|
m_dwVerMajor = 0;
|
|
m_dwVerMinor = 0;
|
|
m_type = wcCustom;
|
|
m_dispid = -1;
|
|
m_bstrName = NULL;
|
|
m_bstrOriginalHref = NULL;
|
|
}
|
|
|
|
~CRunEventState()
|
|
{
|
|
if(m_bstrName != NULL)
|
|
::SysFreeString(m_bstrName);
|
|
|
|
if(m_bstrOriginalHref != NULL)
|
|
::SysFreeString(m_bstrOriginalHref);
|
|
}
|
|
|
|
public:
|
|
inline BOOL IsDTEvent()
|
|
{
|
|
return ( (m_type == EventTypes::typeCustomEvent) ||
|
|
(m_type == EventTypes::typeUnboundTag) ||
|
|
(m_type == EventTypes::typeURLBoundTag) ||
|
|
(m_type == EventTypes::typeEventBoundTag)
|
|
);
|
|
}
|
|
|
|
HRESULT Load(LPSTREAM pStm)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
ULONG cbRead = 0;
|
|
ULONG acbStrings[2];
|
|
BSTR *apbstrStrings[2];
|
|
int cStrings = 2;
|
|
|
|
// TODO: Mopve this into state funcs..
|
|
hr = pStm->Read(this, sizeof(CRunEventState), &cbRead);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
// read design time string lengths from stream
|
|
|
|
hr = pStm->Read(acbStrings, sizeof(acbStrings), &cbRead);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(sizeof(acbStrings) == cbRead, STG_E_DOCFILECORRUPT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
// now check if there are any strings to read
|
|
// if yes then set up array of string pointer addresses
|
|
|
|
apbstrStrings[0] = &m_bstrName;
|
|
apbstrStrings[1] = &m_bstrOriginalHref;
|
|
|
|
hr = ReadStrings(pStm, acbStrings, apbstrStrings, 2);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_INTERNAL_ERRORS);
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
}
|
|
|
|
HRESULT Save(LPSTREAM pStm)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
ULONG cbWritten = 0;
|
|
ULONG acbStrings[2];
|
|
::ZeroMemory(acbStrings, sizeof(acbStrings));
|
|
BSTR abstrStrings[2];
|
|
int cStrings = 2;
|
|
|
|
// set version numbers in node
|
|
|
|
hr = pStm->Write(this, sizeof(CRunEventState), &cbWritten);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(sizeof(CRunEventState) == cbWritten, STG_E_WRITEFAULT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
// set up array of strings to be written to stream and
|
|
// determine how many there will be
|
|
|
|
if (NULL != m_bstrName)
|
|
{
|
|
acbStrings[0] = ::SysStringByteLen(m_bstrName);
|
|
}
|
|
if (NULL != m_bstrOriginalHref)
|
|
{
|
|
acbStrings[1] = ::SysStringByteLen(m_bstrOriginalHref);
|
|
}
|
|
|
|
abstrStrings[0] = m_bstrName;
|
|
abstrStrings[1] = m_bstrOriginalHref;
|
|
|
|
// write string lengths to stream
|
|
|
|
hr = pStm->Write(acbStrings, sizeof(acbStrings), &cbWritten);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(sizeof(acbStrings) == cbWritten, STG_E_WRITEFAULT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
// write strings to stream
|
|
|
|
hr = WriteStrings(pStm, acbStrings, abstrStrings, cStrings);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_INTERNAL_ERRORS);
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
}
|
|
|
|
inline DISPID GetDISPIDDirect() { return m_dispid; }
|
|
inline BSTR GetNameDirect() {return m_bstrName; }
|
|
|
|
public:
|
|
DWORD m_dwVerMajor;
|
|
DWORD m_dwVerMinor;
|
|
WebClassEventTypes m_type; // node type: nested WebClass, URL, events
|
|
DISPID m_dispid; // dispid of node
|
|
BSTR m_bstrName; // name of node
|
|
BSTR m_bstrOriginalHref;
|
|
};
|
|
|
|
|
|
class CRunWebClassStateHeader
|
|
{
|
|
public:
|
|
CRunWebClassStateHeader()
|
|
{
|
|
m_pWebClassState = NULL;
|
|
m_cbWebClassState = 0;
|
|
m_dwWebItemCount = 0;
|
|
}
|
|
|
|
~CRunWebClassStateHeader(){}
|
|
|
|
public:
|
|
CRunWebClassState* m_pWebClassState;
|
|
DWORD m_cbWebClassState;
|
|
DWORD m_dwWebItemCount;
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// File Format:
|
|
//
|
|
// WCS_WEBCLASS structure
|
|
// length of WCS_WEBCLASS.bstrName
|
|
// length of WCS_WEBCLASS.bstrCatastropheURL
|
|
// length of WCS_WEBCLASS.bstrVirtualDirectory
|
|
// WCS_WEBCLASS.bstrName
|
|
// WCS_WEBCLASS.bstrCatastropheURL
|
|
// WCS_WEBCLASS.bstrVirtualDirectory
|
|
//
|
|
// WCS_WEBCLASS.cNodes instances of
|
|
// +-------------------------------
|
|
// | WCS_NODE structure
|
|
// | length of WCS_NODE.bstrName
|
|
// | lengths of other node specific strings
|
|
// | WCS_NODE.bstrName
|
|
// | other node specific strings
|
|
// +-------------------------------
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// inline void WCS_FreeWebClass(WCS_WEBCLASS *pClass)
|
|
//
|
|
// Frees all embedded BSTRs and invokes delete on structure
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
/*
|
|
inline void WCS_FreeWebClass(WCS_WEBCLASS *pClass)
|
|
{
|
|
if (pClass->bstrName != NULL)
|
|
{
|
|
::SysFreeString(pClass->bstrName);
|
|
}
|
|
if (pClass->bstrProgID != NULL)
|
|
{
|
|
::SysFreeString(pClass->bstrProgID);
|
|
}
|
|
if (pClass->bstrCatastropheURL != NULL)
|
|
{
|
|
::SysFreeString(pClass->bstrCatastropheURL);
|
|
}
|
|
if (pClass->bstrVirtualDirectory != NULL)
|
|
{
|
|
::SysFreeString(pClass->bstrVirtualDirectory);
|
|
}
|
|
if (pClass->bstrFirstURL != NULL)
|
|
{
|
|
::SysFreeString(pClass->bstrFirstURL);
|
|
}
|
|
if (pClass->bstrASPName != NULL)
|
|
{
|
|
::SysFreeString(pClass->bstrASPName);
|
|
}
|
|
delete pClass;
|
|
}
|
|
*/
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// inline void WCS_FreeNode(WCS_NODE *pNode)
|
|
//
|
|
// Frees all embedded BSTRs and invokes delete on structure
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
/*
|
|
inline void WCS_FreeNode(WCS_NODE *pNode)
|
|
{
|
|
if (pNode->bstrName != NULL)
|
|
{
|
|
::SysFreeString(pNode->bstrName);
|
|
}
|
|
if (WCS_NODE_TYPE_NESTED_WEBCLASS == pNode->bType)
|
|
{
|
|
if (pNode->bstrProgID != NULL)
|
|
{
|
|
::SysFreeString(pNode->bstrProgID);
|
|
}
|
|
}
|
|
else if ( (WCS_NODE_TYPE_PAGE == pNode->bType) ||
|
|
(WCS_DTNODE_TYPE_PAGE == pNode->bType) )
|
|
{
|
|
if (pNode->bstrTemplate != NULL)
|
|
{
|
|
::SysFreeString(pNode->Page.bstrTemplate);
|
|
}
|
|
if (pNode->Page.bstrToken != NULL)
|
|
{
|
|
::SysFreeString(pNode->Page.bstrToken);
|
|
}
|
|
if (pNode->Page.bstrAppendedParams != NULL)
|
|
{
|
|
::SysFreeString(pNode->Page.bstrAppendedParams);
|
|
}
|
|
}
|
|
delete pNode;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// inline void WCS_FreeDTNode(WCS_NODE *pNode)
|
|
//
|
|
// Frees all embedded BSTRs and invokes delete on structure
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
inline void WCS_FreeDTNode(WCS_DTNODE *pNode)
|
|
{
|
|
if ( (WCS_DTNODE_TYPE_URL_BOUND_TAG == pNode->bType) ||
|
|
(WCS_DTNODE_TYPE_EVENT_BOUND_TAG == pNode->bType) )
|
|
{
|
|
if (NULL != pNode->DTEvent.bstrOriginalHref)
|
|
{
|
|
::SysFreeString(pNode->DTEvent.bstrOriginalHref);
|
|
}
|
|
}
|
|
else if (WCS_DTNODE_TYPE_PAGE == pNode->bType)
|
|
{
|
|
if (NULL != pNode->DTPage.bstrHTMLTemplateSrcName)
|
|
{
|
|
::SysFreeString(pNode->DTPage.bstrHTMLTemplateSrcName);
|
|
}
|
|
}
|
|
WCS_FreeNode(pNode);
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// inline HRESULT WCS_ReadWebClass(IStream *pStream,
|
|
// WCS_WEBCLASS **ppClass)
|
|
//
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
inline HRESULT WCS_ReadWebClass(IStream *pStream, WCS_WEBCLASS **ppClass)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
ULONG cbRead = 0;
|
|
ULONG acbStrings[6];
|
|
BSTR *apbstrStrings[6];
|
|
|
|
// allocate structure
|
|
|
|
*ppClass = new WCS_WEBCLASS;
|
|
CSF_CHECK(*ppClass != NULL, E_OUTOFMEMORY, CSF_TRACE_INTERNAL_ERRORS);
|
|
|
|
// read structure from stream
|
|
|
|
hr = pStream->Read(*ppClass, sizeof(**ppClass), &cbRead);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(sizeof(**ppClass) == cbRead, STG_E_DOCFILECORRUPT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
(*ppClass)->pvData = NULL; // don't take junk pointer value from stream
|
|
|
|
// TODO: need error codes for version incompatibility, handle backlevel formats etc.
|
|
|
|
CSF_CHECK(WCS_WEBCLASS_VER_MAJOR == (*ppClass)->wVerMajor, STG_E_OLDFORMAT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(WCS_WEBCLASS_VER_MAJOR == (*ppClass)->wVerMinor, STG_E_OLDFORMAT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
// read string lengths from stream
|
|
|
|
hr = pStream->Read(acbStrings, sizeof(acbStrings), &cbRead);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(sizeof(acbStrings) == cbRead, STG_E_DOCFILECORRUPT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
// set up array of string pointer addresses
|
|
|
|
apbstrStrings[0] = &((*ppClass)->bstrName);
|
|
apbstrStrings[1] = &((*ppClass)->bstrProgID);
|
|
apbstrStrings[2] = &((*ppClass)->bstrCatastropheURL);
|
|
apbstrStrings[3] = &((*ppClass)->bstrVirtualDirectory);
|
|
apbstrStrings[4] = &((*ppClass)->bstrFirstURL);
|
|
apbstrStrings[5] = &((*ppClass)->bstrASPName);
|
|
|
|
// read strings from stream
|
|
|
|
hr = ReadStrings(pStream, acbStrings, apbstrStrings,
|
|
(sizeof(acbStrings) / sizeof(acbStrings[0])) );
|
|
|
|
CLEANUP:
|
|
if (FAILED(hr) && (*ppClass != NULL))
|
|
{
|
|
WCS_FreeWebClass(*ppClass);
|
|
*ppClass = NULL;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
//
|
|
// inline HRESULT WCS_ReadNodeFromStream(IStream *pStream, WCS_NODE *pNode)
|
|
//
|
|
// Reads a WCS_NODE structure from a stream. Caller passes in node.
|
|
//
|
|
//=--------------------------------------------------------------------------=
|
|
|
|
inline HRESULT WCS_ReadNodeFromStream(IStream *pStream, WCS_NODE *pNode)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
ULONG cbRead = 0;
|
|
ULONG acbStrings[4];
|
|
BSTR *apbstrStrings[4];
|
|
int cStrings = 0;
|
|
|
|
// read structure from stream
|
|
|
|
hr = pStream->Read(pNode, sizeof(*pNode), &cbRead);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(sizeof(*pNode) == cbRead, STG_E_DOCFILECORRUPT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
// TODO: need error codes for version incompatibility, handle backlevel formats etc.
|
|
|
|
CSF_CHECK(WCS_NODE_VER_MAJOR == pNode->wVerMajor, STG_E_OLDFORMAT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(WCS_NODE_VER_MINOR == pNode->wVerMinor, STG_E_OLDFORMAT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
// set up array of string pointer addresses according to node type
|
|
|
|
apbstrStrings[0] = &(pNode->bstrName);
|
|
|
|
if ( (WCS_NODE_TYPE_NESTED_WEBCLASS == pNode->bType) ||
|
|
(WCS_DTNODE_TYPE_NESTED_WEBCLASS == pNode->bType) )
|
|
{
|
|
apbstrStrings[1] = &(pNode->bstrProgID);
|
|
cStrings = 2;
|
|
}
|
|
else if ( (WCS_NODE_TYPE_PAGE == pNode->bType) ||
|
|
(WCS_DTNODE_TYPE_PAGE == pNode->bType) )
|
|
{
|
|
apbstrStrings[1] = &(pNode->bstrTemplate);
|
|
apbstrStrings[2] = &(pNode->bstrToken);
|
|
apbstrStrings[3] = &(pNode->bstrAppendedParams);
|
|
cStrings = 4;
|
|
}
|
|
else if ( (WCS_NODE_TYPE_EVENT == bType) ||
|
|
IsDTEvent(bType) )
|
|
{
|
|
cStrings = 1;
|
|
}
|
|
else
|
|
{
|
|
CSF_CHECK(FALSE, STG_E_DOCFILECORRUPT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
}
|
|
|
|
// read string lengths from stream
|
|
|
|
hr = pStream->Read(acbStrings, sizeof(acbStrings), &cbRead);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(sizeof(acbStrings) == cbRead, STG_E_DOCFILECORRUPT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
// read strings from stream
|
|
|
|
hr = ReadStrings(pStream, acbStrings, apbstrStrings, cStrings);
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// inline HRESULT WCS_ReadNode(IStream *pStream, WCS_NODE **ppNode)
|
|
//
|
|
// Allocates a WCS_NODE structure and reads its contents from the
|
|
// stream.
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
inline HRESULT WCS_ReadNode(IStream *pStream, WCS_NODE **ppNode)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
// allocate structure
|
|
|
|
*ppNode = new WCS_NODE;
|
|
CSF_CHECK(*ppNode != NULL, E_OUTOFMEMORY, CSF_TRACE_INTERNAL_ERRORS);
|
|
|
|
// read node in from stream
|
|
|
|
hr = WCS_ReadNodeFromStream(pStream, *ppNode);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_INTERNAL_ERRORS);
|
|
|
|
CLEANUP:
|
|
if (FAILED(hr) && (*ppNode != NULL))
|
|
{
|
|
WCS_FreeNode(*ppNode);
|
|
*ppNode = NULL;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
//
|
|
// inline HRESULT WCS_ReadDTNode(IStream *pStream, WCS_DTNODE **ppNode)
|
|
//
|
|
// Allocates a WCS_DTNODE and reads its contents from the stream.
|
|
//
|
|
//=--------------------------------------------------------------------------=
|
|
|
|
inline HRESULT WCS_ReadDTNode(IStream *pStream, WCS_DTNODE **ppNode)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
ULONG cbRead = 0;
|
|
ULONG acbStrings[1];
|
|
BSTR *apbstrStrings[1];
|
|
int cStrings = 0;
|
|
|
|
// allocate structure
|
|
|
|
*ppNode = new WCS_DTNODE;
|
|
CSF_CHECK(*ppNode != NULL, E_OUTOFMEMORY, CSF_TRACE_INTERNAL_ERRORS);
|
|
|
|
// read base class WCS_NODE first
|
|
|
|
hr = WCS_ReadNodeFromStream(pStream, *ppNode);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_INTERNAL_ERRORS);
|
|
|
|
// read design time fields
|
|
|
|
if (WCS_DTNODE_TYPE_PAGE == (*ppNode)->bType)
|
|
{
|
|
hr = pStream->Read(&(*ppNode)->DTPage, sizeof((*ppNode)->DTPage), &cbRead);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(sizeof((*ppNode)->DTPage) == cbRead, STG_E_DOCFILECORRUPT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
}
|
|
else if (WCS_DTNODE_TYPE_NESTED_WEBCLASS != (*ppNode)->bType)
|
|
{
|
|
hr = pStream->Read(&(*ppNode)->DTEvent, sizeof((*ppNode)->DTEvent), &cbRead);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(sizeof((*ppNode)->DTEvent) == cbRead, STG_E_DOCFILECORRUPT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
}
|
|
|
|
// read design time string lengths from stream
|
|
|
|
hr = pStream->Read(acbStrings, sizeof(acbStrings), &cbRead);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(sizeof(acbStrings) == cbRead, STG_E_DOCFILECORRUPT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
// now check if there are any strings to read
|
|
// if yes then set up array of string pointer addresses
|
|
|
|
if (0 == acbStrings[0])
|
|
{
|
|
// There are no strings to read so store NULL pointers
|
|
if (WCS_DTNODE_TYPE_PAGE == (*ppNode)->bType)
|
|
{
|
|
(*ppNode)->DTPage.bstrHTMLTemplateSrcName = NULL;
|
|
}
|
|
else if (WCS_DTNODE_TYPE_NESTED_WEBCLASS != (*ppNode)->bType)
|
|
{
|
|
(*ppNode)->DTEvent.bstrOriginalHref = NULL;
|
|
}
|
|
goto CLEANUP;
|
|
}
|
|
else // There are strings so read them from the stream
|
|
{
|
|
if (WCS_DTNODE_TYPE_PAGE == (*ppNode)->bType)
|
|
{
|
|
apbstrStrings[0] = &((*ppNode)->DTPage.bstrHTMLTemplateSrcName);
|
|
}
|
|
else if (WCS_DTNODE_TYPE_NESTED_WEBCLASS != (*ppNode)->bType)
|
|
{
|
|
apbstrStrings[0] = &((*ppNode)->DTEvent.bstrOriginalHref);
|
|
}
|
|
cStrings++;
|
|
}
|
|
|
|
// read strings from stream
|
|
|
|
if (cStrings > 0)
|
|
{
|
|
hr = ReadStrings(pStream, acbStrings, apbstrStrings, cStrings);
|
|
}
|
|
|
|
CLEANUP:
|
|
if (FAILED(hr) && (*ppNode != NULL))
|
|
{
|
|
WCS_FreeDTNode(*ppNode);
|
|
*ppNode = NULL;
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// inline HRESULT WCS_WriteWebClass(IStream *pStream, WCS_WEBCLASS *pClass)
|
|
//
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
inline HRESULT WCS_WriteWebClass(IStream *pStream, WCS_WEBCLASS *pClass)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
ULONG cbWritten = 0;
|
|
ULONG acbStrings[6];
|
|
BSTR abstrStrings[6];
|
|
|
|
// set version numbers
|
|
|
|
pClass->wVerMajor = WCS_WEBCLASS_VER_MAJOR;
|
|
pClass->wVerMinor = WCS_WEBCLASS_VER_MAJOR;
|
|
|
|
// write WebClass structure to stream
|
|
|
|
hr = pStream->Write(pClass, sizeof(*pClass), &cbWritten);
|
|
CSF_CHECK(hr == S_OK, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(cbWritten == sizeof(*pClass), STG_E_WRITEFAULT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
// get lengths of strings and write them to stream
|
|
|
|
acbStrings[0] = SysStringByteLen(pClass->bstrName);
|
|
acbStrings[1] = SysStringByteLen(pClass->bstrProgID);
|
|
acbStrings[2] = SysStringByteLen(pClass->bstrCatastropheURL);
|
|
acbStrings[3] = SysStringByteLen(pClass->bstrVirtualDirectory);
|
|
acbStrings[4] = SysStringByteLen(pClass->bstrFirstURL);
|
|
acbStrings[5] = SysStringByteLen(pClass->bstrASPName);
|
|
|
|
hr = pStream->Write(acbStrings, sizeof(acbStrings), &cbWritten);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(cbWritten == sizeof(acbStrings), STG_E_WRITEFAULT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
// set up array of pointers to strings to be written to stream
|
|
|
|
abstrStrings[0] = pClass->bstrName;
|
|
abstrStrings[1] = pClass->bstrProgID;
|
|
abstrStrings[2] = pClass->bstrCatastropheURL;
|
|
abstrStrings[3] = pClass->bstrVirtualDirectory;
|
|
abstrStrings[4] = pClass->bstrFirstURL;
|
|
abstrStrings[5] = pClass->bstrASPName;
|
|
|
|
// write strings to stream
|
|
|
|
hr = WriteStrings(pStream, acbStrings, abstrStrings,
|
|
(sizeof(acbStrings) / sizeof(acbStrings[0])) );
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
//
|
|
// inline HRESULT WCS_WriteNode(IStream *pStream, WCS_NODE *pNode)
|
|
//
|
|
//
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
inline HRESULT WCS_WriteNode(IStream *pStream, WCS_NODE *pNode)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
ULONG cbWritten = 0;
|
|
ULONG acbStrings[4];
|
|
BSTR abstrStrings[4];
|
|
int cStrings = 0;
|
|
|
|
// set version numbers in node
|
|
|
|
pNode->wVerMajor = WCS_NODE_VER_MAJOR;
|
|
pNode->wVerMinor = WCS_NODE_VER_MINOR;
|
|
|
|
// write node structure to stream
|
|
|
|
hr = pStream->Write(pNode, sizeof(*pNode), &cbWritten);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(sizeof(*pNode) == cbWritten, STG_E_WRITEFAULT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
// set up array of strings to be written to stream and
|
|
// determine how many there will be
|
|
|
|
abstrStrings[0] = pNode->bstrName;
|
|
acbStrings[0] = ::SysStringByteLen(pNode->bstrName);
|
|
|
|
if ( (WCS_NODE_TYPE_NESTED_WEBCLASS == pNode->bType) ||
|
|
(WCS_DTNODE_TYPE_NESTED_WEBCLASS == pNode->bType) )
|
|
{
|
|
abstrStrings[1] = pNode->Nested.bstrProgID;
|
|
acbStrings[1] = ::SysStringByteLen(pNode->Nested.bstrProgID);
|
|
cStrings = 2;
|
|
}
|
|
else if ( (WCS_NODE_TYPE_PAGE == pNode->bType) ||
|
|
(WCS_DTNODE_TYPE_PAGE == pNode->bType) )
|
|
{
|
|
abstrStrings[1] = pNode->Page.bstrTemplate;
|
|
acbStrings[1] = ::SysStringByteLen(pNode->Page.bstrTemplate);
|
|
abstrStrings[2] = pNode->Page.bstrToken;
|
|
acbStrings[2] = ::SysStringByteLen(pNode->Page.bstrToken);
|
|
abstrStrings[3] = pNode->Page.bstrAppendedParams;
|
|
acbStrings[3] = ::SysStringByteLen(pNode->Page.bstrAppendedParams);
|
|
cStrings = 4;
|
|
}
|
|
else if ( (WCS_NODE_TYPE_EVENT == pNode->bType) ||
|
|
WCS_IsDTEvent(pNode->bType) )
|
|
{
|
|
cStrings = 1;
|
|
}
|
|
else
|
|
{
|
|
CSF_CHECK(FALSE, E_INVALIDARG, CSF_TRACE_INTERNAL_ERRORS);
|
|
}
|
|
|
|
// write string lengths to stream
|
|
|
|
hr = pStream->Write(acbStrings, sizeof(acbStrings), &cbWritten);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(sizeof(acbStrings) == cbWritten, STG_E_WRITEFAULT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
// write strings to stream
|
|
|
|
hr = WriteStrings(pStream, acbStrings, abstrStrings, cStrings);
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
}
|
|
|
|
//=--------------------------------------------------------------------------=
|
|
//
|
|
// inline HRESULT WCS_WriteDTNode(IStream *pStream, WCS_DTNODE *pNode)
|
|
//
|
|
// Write design time node. Write the base class runtime node and then
|
|
// then extra stuff in the design time node.
|
|
//
|
|
//=--------------------------------------------------------------------------=
|
|
|
|
inline HRESULT WCS_WriteDTNode(IStream *pStream, WCS_DTNODE *pNode)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
ULONG cbWritten = 0;
|
|
ULONG acbStrings[1] = { 0 };
|
|
BSTR abstrStrings[1];
|
|
int cStrings = 0;
|
|
|
|
// write run time node first
|
|
|
|
hr = WCS_WriteNode(pStream, pNode);
|
|
CSF_CHECK(hr == S_OK, hr, CSF_TRACE_INTERNAL_ERRORS);
|
|
|
|
// write design time fields
|
|
|
|
if (WCS_DTNODE_TYPE_PAGE == pNode->bType)
|
|
{
|
|
hr = pStream->Write(&pNode->DTPage, sizeof(pNode->DTPage), &cbWritten);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(sizeof(pNode->DTPage) == cbWritten, STG_E_WRITEFAULT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
if (NULL != pNode->DTPage.bstrHTMLTemplateSrcName)
|
|
{
|
|
abstrStrings[0] = pNode->DTPage.bstrHTMLTemplateSrcName;
|
|
acbStrings[0] = ::SysStringByteLen(pNode->DTPage.bstrHTMLTemplateSrcName);
|
|
cStrings++;
|
|
}
|
|
}
|
|
else if (WCS_DTNODE_TYPE_NESTED_WEBCLASS != pNode->bType)
|
|
{
|
|
hr = pStream->Write(&pNode->DTEvent, sizeof(pNode->DTEvent), &cbWritten);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(sizeof(pNode->DTEvent) == cbWritten, STG_E_WRITEFAULT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
if (NULL != pNode->DTEvent.bstrOriginalHref)
|
|
{
|
|
abstrStrings[0] = pNode->DTEvent.bstrOriginalHref;
|
|
acbStrings[0] = ::SysStringByteLen(pNode->DTEvent.bstrOriginalHref);
|
|
cStrings++;
|
|
}
|
|
}
|
|
|
|
hr = pStream->Write(acbStrings, sizeof(acbStrings), &cbWritten);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_EXTERNAL_ERRORS);
|
|
CSF_CHECK(sizeof(acbStrings) == cbWritten, STG_E_WRITEFAULT, CSF_TRACE_EXTERNAL_ERRORS);
|
|
|
|
if (cStrings > 0)
|
|
{
|
|
hr = WriteStrings(pStream, acbStrings, abstrStrings, cStrings);
|
|
CSF_CHECK(S_OK == hr, hr, CSF_TRACE_INTERNAL_ERRORS);
|
|
}
|
|
|
|
CLEANUP:
|
|
return hr;
|
|
}
|
|
*/
|
|
|
|
|
|
#define _WBCLSSER_H_
|
|
#endif // _WBCLSSER_H_
|