windows-nt/Source/XPSP1/NT/com/ole32/stg/h/expparam.hxx

505 lines
14 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
//+--------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1998 - 1998.
//
// File: expparam.hxx
//
// Contents: Standard Parameter validation for Exposed Interfaces
//
// History: 11-Feb-98 BChapman Created
//
//---------------------------------------------------------------
#ifndef _EXPPARAM_HXX_
#define _EXPPARAM_HXX_
#include <docfilep.hxx>
#include <funcs.hxx>
//
// I can't actually inherit from the real interfaces and declare the
// methods "static inline" like I want, because "virtual" is incompatible with
// both "static" and "inline". So don't inherit in the final version.
//
#if 0
#define PUBLIC_INHERIT :public IStorage, public IStream, \
public ILockBytes, public IEnumSTATSTG
#define METHODIMP STDMETHODIMP
#define METHODIMP_(x) STDMETHODIMP_(x)
#else
#define PUBLIC_INHERIT
#define METHODIMP static inline STDMETHODIMP
#define METHODIMP_(x) static inline STDMETHODIMP_(x)
#endif
#define ChkErr(x) { HRESULT sc; if( FAILED( sc = (x) ) ) return sc; }
#if DBG == 1
#define EXP_VALIDATE(comp, x) \
{ \
if (FAILED(sc = CExpParameterValidate::x)) \
{ \
comp##DebugOut(( DEB_ERROR, \
"Parameter Error %lX at %s:%d\n", \
sc, __FILE__, __LINE__)); \
return sc; \
} \
}
#else
#define EXP_VALIDATE(comp, x) \
{ \
if (FAILED(sc = CExpParameterValidate::x))\
return sc; \
}
#endif // DBG
class CExpParameterValidate PUBLIC_INHERIT
{
public:
//
// The IUnknown methods First.
//
METHODIMP QueryInterface( REFIID riid,
void** ppvObject )
{
ChkErr( ValidateOutPtrBuffer( ppvObject ) );
*ppvObject = NULL;
ChkErr( ValidateIid( riid ) );
return S_OK;
}
#if 0
//
// Addref and Release are troublesome because they don't
// return HRESULTS. Luckly they have no parameters and are
// therefore unnecessary.
//
METHODIMP_(ULONG) AddRef( void )
{
return S_OK;
}
METHODIMP_(ULONG) Release( void )
{
return S_OK;
}
#endif
//
// All the other methods in Alphabetical Order.
//
// IEnumSTATSTG
METHODIMP Clone( IEnumSTATSTG** ppenum )
{
ChkErr( ValidateOutPtrBuffer( ppenum ) );
*ppenum = NULL;
return S_OK;
}
// IStream
METHODIMP Clone( IStream** ppstm)
{
ChkErr( ValidateOutPtrBuffer( ppstm ) );
*ppstm = NULL;
return S_OK;
}
// IStream
METHODIMP CopyTo( IStream* pstm,
ULARGE_INTEGER cb,
ULARGE_INTEGER* pcbRead,
ULARGE_INTEGER* pcbWritten )
{
if( NULL != pcbRead )
{
ChkErr( ValidateOutBuffer( pcbRead, sizeof( ULARGE_INTEGER ) ) );
pcbRead->QuadPart = 0;
}
if( NULL != pcbWritten )
{
ChkErr( ValidateOutBuffer( pcbWritten, sizeof(ULARGE_INTEGER) ) );
pcbWritten->QuadPart = 0;
}
ChkErr( ValidateInterface(pstm, IID_IStream) );
return S_OK;
}
// IStorage
METHODIMP CopyTo( DWORD ciidExclude,
const IID* rgiidExclude,
SNB snbExclude,
IStorage* pstgDest)
{
DWORD i;
ChkErr( ValidateInterface( pstgDest, IID_IStorage ) );
if( NULL != rgiidExclude )
{
Win4Assert(sizeof(IID)*ciidExclude <= 0xffffUL);
ChkErr( ValidateBuffer( rgiidExclude,
(size_t)(sizeof(IID)*ciidExclude ) ) );
//
// This check may be useless. I think it is checking if the address
// of given stack variable is a valid address (duh!)
// This check has been in the code a long time make sure in the debugger!
//
for (i = 0; i < ciidExclude; i++)
ChkErr(ValidateIid(rgiidExclude[i]));
}
if( NULL != snbExclude )
ChkErr( ValidateSNB( snbExclude ) );
return S_OK;
}
// IStream, IStorage
METHODIMP Commit( DWORD grfCommitFlags )
{
ChkErr( VerifyCommitFlags( grfCommitFlags ) );
return S_OK;
}
// IStorage
METHODIMP CreateStorage( const OLECHAR* pwcsName,
DWORD grfMode,
DWORD reserved1,
DWORD reserved2,
IStorage** ppstg)
{
ChkErr( ValidateOutPtrBuffer( ppstg ) );
*ppstg = NULL;
ChkErr( CheckName(pwcsName) );
if( reserved1 != 0 || reserved2 != 0 )
return STG_E_INVALIDPARAMETER;
ChkErr( VerifyPerms( grfMode, FALSE ) );
if( grfMode & ( STGM_PRIORITY | STGM_DELETEONRELEASE ) )
return STG_E_INVALIDFUNCTION;
return S_OK;
}
// IStorage
METHODIMP CreateStream( const OLECHAR* pwcsName,
DWORD grfMode,
DWORD reserved1,
DWORD reserved2,
IStream** ppstm)
{
ChkErr( ValidateOutPtrBuffer( ppstm ) );
*ppstm = NULL;
ChkErr( CheckName( pwcsName ) );
if( reserved1 != 0 || reserved2 != 0 )
return STG_E_INVALIDPARAMETER;
ChkErr( VerifyPerms( grfMode, FALSE ) );
if( grfMode & ( STGM_CONVERT | STGM_TRANSACTED | STGM_PRIORITY |
STGM_DELETEONRELEASE ) )
{
return STG_E_INVALIDFUNCTION;
}
return S_OK;
}
// IStorage
METHODIMP DestroyElement( const OLECHAR* pwcsName )
{
ChkErr( CheckName( pwcsName ) );
return S_OK;
}
// IStorage
METHODIMP EnumElements( DWORD reserved1,
void* reserved2,
DWORD reserved3,
IEnumSTATSTG** ppenum)
{
ChkErr( ValidateOutPtrBuffer( ppenum ) );
*ppenum = NULL;
if( reserved1 != 0 || reserved2 != NULL || reserved3 != 0 )
return STG_E_INVALIDPARAMETER;
return S_OK;
}
// ILockBytes
METHODIMP Flush( void )
{
return S_OK;
}
// IStream, ILockBytes
METHODIMP LockRegion( ULARGE_INTEGER libOffset,
ULARGE_INTEGER cb,
DWORD dwLockType )
{
ChkErr( VerifyLockType( dwLockType ) );
return S_OK;
}
// IStorage
METHODIMP MoveElementTo( const OLECHAR* pwcsName,
IStorage* pstgDest,
const OLECHAR* pwcsNewName,
DWORD grfFlags)
{
ChkErr( CheckName( pwcsName ) );
ChkErr( CheckName( pwcsNewName ) );
ChkErr( VerifyMoveFlags( grfFlags ) );
ChkErr( ValidateInterface( pstgDest, IID_IStorage ) );
return S_OK;
}
// IEnumSTATSTG
METHODIMP Next( ULONG celt,
STATSTG FAR *rgelt,
ULONG *pceltFetched)
{
if (pceltFetched)
{
ChkErr( ValidateOutBuffer( pceltFetched, sizeof(ULONG) ) );
*pceltFetched = 0;
}
else if (celt != 1)
return STG_E_INVALIDPARAMETER;
ChkErr( ValidateOutBuffer( rgelt, sizeof(STATSTGW)*celt) );
memset( rgelt, 0, (size_t)(sizeof(STATSTGW)*celt ) );
return S_OK;
}
// IStorage
METHODIMP OpenStorage( const OLECHAR* pwcsName,
IStorage* pstgPriority,
DWORD grfMode,
SNB snbExclude,
DWORD reserved,
IStorage** ppstg)
{
ChkErr( ValidateOutPtrBuffer( ppstg ) );
*ppstg = NULL;
ChkErr( CheckName( pwcsName ) );
if( reserved != 0)
return STG_E_INVALIDPARAMETER;
ChkErr( VerifyPerms( grfMode, FALSE ) );
if( grfMode & (STGM_CREATE | STGM_CONVERT ) )
return STG_E_INVALIDFLAG;
if( NULL != pstgPriority
|| ( grfMode & ( STGM_PRIORITY | STGM_DELETEONRELEASE ) ) )
{
return STG_E_INVALIDFUNCTION;
}
return S_OK;
}
// IStorage
METHODIMP OpenStream( const OLECHAR* pwcsName,
void* reserved1,
DWORD grfMode,
DWORD reserved2,
IStream** ppstm)
{
ChkErr(ValidateOutPtrBuffer(ppstm));
*ppstm = NULL;
ChkErr( CheckName( pwcsName ) );
if( reserved1 != NULL || reserved2 != 0 )
return STG_E_INVALIDPARAMETER;
ChkErr( VerifyPerms( grfMode, FALSE ) );
if( grfMode & (STGM_CREATE | STGM_CONVERT ) )
return STG_E_INVALIDFLAG;
if( grfMode & (STGM_TRANSACTED | STGM_PRIORITY |
STGM_DELETEONRELEASE ) )
return STG_E_INVALIDFUNCTION;
return S_OK;
}
// IStream
METHODIMP Read( void* pv,
ULONG cb,
ULONG* pcbRead)
{
if (NULL != pcbRead)
{
ChkErr( ValidateOutBuffer( pcbRead, sizeof(ULONG) ) );
*pcbRead = 0;
}
ChkErr( ValidateHugeOutBuffer( pv, cb ) );
return S_OK;
}
// ILockBytes
METHODIMP ReadAt( ULARGE_INTEGER ulOffset,
void* pv,
ULONG cb,
ULONG* pcbRead )
{
if (NULL != pcbRead)
{
ChkErr( ValidateOutBuffer( pcbRead, sizeof(ULONG) ) );
*pcbRead = 0;
}
ChkErr( ValidateHugeOutBuffer( pv, cb ) );
return S_OK;
}
// IStorage
METHODIMP RenameElement( const OLECHAR* pwcsOldName,
const OLECHAR* pwcsNewName)
{
ChkErr( CheckName( pwcsOldName ) );
ChkErr( CheckName( pwcsNewName ) );
return S_OK;
}
// IEnumSTATSTG
METHODIMP Reset()
{
return S_OK;
}
// IStream, IStorage
METHODIMP Revert( void )
{
return S_OK;
}
// IStream
METHODIMP Seek( LARGE_INTEGER dlibMove,
DWORD dwOrigin,
ULARGE_INTEGER* plibNewPosition )
{
if( plibNewPosition )
{
ChkErr( ValidateOutBuffer( plibNewPosition, sizeof(ULARGE_INTEGER ) ) );
plibNewPosition->QuadPart = 0;
}
switch( dwOrigin )
{
case STREAM_SEEK_SET:
case STREAM_SEEK_CUR:
case STREAM_SEEK_END:
break;
default:
return STG_E_INVALIDFUNCTION;
}
return S_OK;
}
// IStorage
METHODIMP SetClass( REFCLSID clsid)
{
ChkErr( ValidateBuffer( &clsid, sizeof( CLSID ) ) );
return S_OK;
}
// IStorage
METHODIMP SetElementTimes( const OLECHAR* pwcsName,
const FILETIME* pctime,
const FILETIME* patime,
const FILETIME* pmtime)
{
if( NULL != pwcsName )
ChkErr( CheckName( pwcsName ) );
if( NULL != pctime )
ChkErr( ValidateBuffer( pctime, sizeof( FILETIME ) ) );
if( NULL != patime )
ChkErr( ValidateBuffer( patime, sizeof( FILETIME ) ) );
if( NULL != pmtime )
ChkErr( ValidateBuffer( pmtime, sizeof( FILETIME ) ) );
return S_OK;
}
// IStream, ILockBytes
METHODIMP SetSize( ULARGE_INTEGER libNewSize )
{
return S_OK;
}
// IStorage
METHODIMP SetStateBits( DWORD grfStateBits,
DWORD grfMask )
{
// We could insist that both args be 0.
// But we never have in the past.
return S_OK;
}
// IEnumSTATSTG
METHODIMP Skip( ULONG celt )
{
// I would like to do some sanity testing but the value
// isn't even signed. All bit values are technically valid.
return S_OK;
}
// IStream, IStorage, ILockBytes
METHODIMP Stat( STATSTG* pstatstg,
DWORD grfStatFlag )
{
ChkErr( ValidateOutBuffer( pstatstg, sizeof( STATSTGW ) ) );
ChkErr( VerifyStatFlag( grfStatFlag ) );
return S_OK;
}
// IStream, ILockBytes
METHODIMP UnlockRegion( ULARGE_INTEGER libOffset,
ULARGE_INTEGER cb,
DWORD dwLockType )
{
ChkErr( VerifyLockType( dwLockType ) );
return S_OK;
}
// IStream
METHODIMP Write( const void* pv,
ULONG cb,
ULONG* pcbWritten )
{
if (NULL != pcbWritten)
{
ChkErr( ValidateOutBuffer( pcbWritten, sizeof(ULONG) ) );
*pcbWritten = 0;
}
ChkErr( ValidateHugeBuffer( pv, cb ) );
return S_OK;
}
// ILockBytes
METHODIMP WriteAt( ULARGE_INTEGER ulOffset,
const void *pv,
ULONG cb,
ULONG *pcbWritten )
{
if (NULL != pcbWritten)
{
ChkErr( ValidateOutBuffer( pcbWritten, sizeof(ULONG) ) );
*pcbWritten = 0;
}
ChkErr( ValidateHugeBuffer( pv, cb ) );
return S_OK;
}
};
#endif // _EXPPARAM_HXX_