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.
335 lines
7.2 KiB
335 lines
7.2 KiB
/******************************************************************************
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
ScriptableStream.cpp
|
|
|
|
Abstract:
|
|
This file contains the implementation of the CPCHScriptableStream class,
|
|
which is a scriptable wrapper for IStream.
|
|
|
|
Revision History:
|
|
Davide Massarenti (Dmassare) 10/06/2000
|
|
created
|
|
|
|
******************************************************************************/
|
|
|
|
#include "stdafx.h"
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT CPCHScriptableStream::ReadToHGLOBAL( /*[in]*/ long lCount, /*[out]*/ HGLOBAL& hg, /*[out]*/ ULONG& lReadTotal )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHScriptableStream::ReadToHGLOBAL" );
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
lReadTotal = 0;
|
|
|
|
|
|
if(lCount < 0)
|
|
{
|
|
static const ULONG c_BUFSIZE = 4096;
|
|
|
|
ULONG lRead;
|
|
|
|
__MPC_EXIT_IF_ALLOC_FAILS(hr, hg, ::GlobalAlloc( GMEM_FIXED, c_BUFSIZE ));
|
|
|
|
while(1)
|
|
{
|
|
HGLOBAL hg2;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::FileStream::Read( &((BYTE*)hg)[lReadTotal], c_BUFSIZE, &lRead ));
|
|
|
|
if(hr == S_FALSE || lRead == 0) break;
|
|
|
|
lReadTotal += lRead;
|
|
|
|
//
|
|
// Increase buffer.
|
|
//
|
|
__MPC_EXIT_IF_ALLOC_FAILS(hr, hg2, ::GlobalReAlloc( hg, lReadTotal + c_BUFSIZE, 0 ));
|
|
hg = hg2;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
__MPC_EXIT_IF_ALLOC_FAILS(hr, hg, ::GlobalAlloc( GMEM_FIXED, lCount ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::FileStream::Read( hg, lCount, &lReadTotal ));
|
|
}
|
|
|
|
|
|
hr = S_OK;
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
STDMETHODIMP CPCHScriptableStream::get_Size( /*[out, retval]*/ long *plSize )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHScriptableStream::get_Size" );
|
|
|
|
HRESULT hr;
|
|
STATSTG stat;
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_POINTER_AND_SET(plSize,0);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::FileStream::Stat( &stat, STATFLAG_NONAME ));
|
|
|
|
*plSize = (long)stat.cbSize.QuadPart;
|
|
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
|
|
STDMETHODIMP CPCHScriptableStream::Read( /*[in]*/ long lCount, /*[out, retval]*/ VARIANT *pvData )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHScriptableStream::Read" );
|
|
|
|
HRESULT hr;
|
|
CComVariant vArray;
|
|
HGLOBAL hg = NULL;
|
|
ULONG lReadTotal;
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_NOTNULL(pvData);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, ReadToHGLOBAL( lCount, hg, lReadTotal ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertBufferToVariant( (BYTE*)hg, (DWORD)lReadTotal, vArray ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, vArray.Detach( pvData ));
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
if(hg) ::GlobalFree( hg );
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
STDMETHODIMP CPCHScriptableStream::ReadHex( /*[in]*/ long lCount, /*[out, retval]*/ BSTR *pbstrData )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHScriptableStream::ReadHex" );
|
|
|
|
HRESULT hr;
|
|
HGLOBAL hg = NULL;
|
|
ULONG lReadTotal;
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_POINTER_AND_SET(pbstrData,0);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, ReadToHGLOBAL( lCount, hg, lReadTotal ));
|
|
|
|
if(lReadTotal)
|
|
{
|
|
CComBSTR bstrHex;
|
|
HGLOBAL hg2;
|
|
|
|
//
|
|
// Trim down the size of the HGLOBAL.
|
|
//
|
|
__MPC_EXIT_IF_ALLOC_FAILS(hr, hg2, ::GlobalReAlloc( hg, lReadTotal, 0 ));
|
|
hg = hg2;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertHGlobalToHex( hg, bstrHex ));
|
|
|
|
*pbstrData = bstrHex.Detach();
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
if(hg) ::GlobalFree( hg );
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
STDMETHODIMP CPCHScriptableStream::Write( /*[in]*/ long lCount, /*[in]*/ VARIANT vData, /*[out, retval]*/ long *plWritten )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHScriptableStream::get_Size" );
|
|
|
|
HRESULT hr;
|
|
BYTE* rgBuf = NULL;
|
|
DWORD dwLen = 0;
|
|
bool fAccessData = false;
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_POINTER_AND_SET(plWritten,0);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
switch(vData.vt)
|
|
{
|
|
case VT_EMPTY:
|
|
case VT_NULL:
|
|
break;
|
|
|
|
case VT_ARRAY | VT_UI1:
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertVariantToBuffer( &vData, rgBuf, dwLen ));
|
|
break;
|
|
|
|
case VT_ARRAY | VT_VARIANT:
|
|
{
|
|
long lBound; ::SafeArrayGetLBound( vData.parray, 1, &lBound );
|
|
long uBound; ::SafeArrayGetUBound( vData.parray, 1, &uBound );
|
|
VARIANT* pSrc;
|
|
DWORD dwPos;
|
|
|
|
dwLen = uBound - lBound + 1;
|
|
|
|
__MPC_EXIT_IF_ALLOC_FAILS(hr, rgBuf, new BYTE[dwLen]);
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, ::SafeArrayAccessData( vData.parray, (LPVOID*)&pSrc ));
|
|
fAccessData = true;
|
|
|
|
|
|
for(dwPos=0; dwPos<dwLen; dwPos++, pSrc++)
|
|
{
|
|
CComVariant v;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, ::VariantChangeType( &v, pSrc, 0, VT_UI1 ));
|
|
|
|
rgBuf[dwPos] = v.bVal;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
if(dwLen && rgBuf)
|
|
{
|
|
ULONG lWritten;
|
|
|
|
//
|
|
// Just write the requested number of bytes.
|
|
//
|
|
if(lCount >= 0 && dwLen > lCount) dwLen = lCount;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::FileStream::Write( rgBuf, dwLen, &lWritten ));
|
|
|
|
*plWritten = lWritten;
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
if(fAccessData) ::SafeArrayUnaccessData( vData.parray );
|
|
|
|
delete [] rgBuf;
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
STDMETHODIMP CPCHScriptableStream::WriteHex( /*[in]*/ long lCount, /*[in]*/ BSTR bstrData, /*[out, retval]*/ long *plWritten )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHScriptableStream::get_Size" );
|
|
|
|
HRESULT hr;
|
|
HGLOBAL hg = NULL;
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_POINTER_AND_SET(plWritten,0);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
if(STRINGISPRESENT(bstrData))
|
|
{
|
|
CComBSTR bstrHex( bstrData );
|
|
ULONG lWritten = 0;
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertHexToHGlobal( bstrHex, hg, true ));
|
|
|
|
if(hg)
|
|
{
|
|
DWORD dwSize = ::GlobalSize( hg );
|
|
|
|
//
|
|
// Just write the requested number of bytes.
|
|
//
|
|
if(lCount >= 0 && lCount > dwSize) lCount = dwSize;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::FileStream::Write( (BYTE*)hg, lCount, &lWritten ));
|
|
}
|
|
|
|
*plWritten = lWritten;
|
|
}
|
|
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
if(hg) ::GlobalFree( hg );
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
STDMETHODIMP CPCHScriptableStream::Seek( /*[in]*/ long lOffset, /*[in]*/ BSTR bstrOrigin, /*[out, retval]*/ long *plNewPos )
|
|
{
|
|
__HCP_FUNC_ENTRY( "CPCHScriptableStream::get_Size" );
|
|
|
|
HRESULT hr;
|
|
DWORD dwOrigin;
|
|
LARGE_INTEGER liMove;
|
|
ULARGE_INTEGER liNewPos;
|
|
|
|
__MPC_PARAMCHECK_BEGIN(hr)
|
|
__MPC_PARAMCHECK_STRING_NOT_EMPTY(bstrOrigin);
|
|
__MPC_PARAMCHECK_POINTER_AND_SET(plNewPos,0);
|
|
__MPC_PARAMCHECK_END();
|
|
|
|
|
|
if (!_wcsicmp( bstrOrigin, L"SET" )) dwOrigin = STREAM_SEEK_SET;
|
|
else if(!_wcsicmp( bstrOrigin, L"CUR" )) dwOrigin = STREAM_SEEK_CUR;
|
|
else if(!_wcsicmp( bstrOrigin, L"END" )) dwOrigin = STREAM_SEEK_END;
|
|
else __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG);
|
|
|
|
|
|
liMove.QuadPart = lOffset;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::FileStream::Seek( liMove, dwOrigin, &liNewPos ));
|
|
|
|
*plNewPos = liNewPos.QuadPart;
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__HCP_FUNC_CLEANUP;
|
|
|
|
__HCP_FUNC_EXIT(hr);
|
|
}
|
|
|
|
STDMETHODIMP CPCHScriptableStream::Close()
|
|
{
|
|
MPC::FileStream::Close();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|