|
|
/******************************************************************************
Copyright (c) 1999 Microsoft Corporation
Module Name: Stream.cpp
Abstract: This file contains the implementation of the MPC::*Stream classes.
Revision History: Davide Massarenti (Dmassare) 07/14/99 created
******************************************************************************/
#include "stdafx.h"
/////////////////////////////////////////////////////////////////////////////
STDMETHODIMP MPC::BaseStream::Read( /*[out]*/ void* pv , /*[in] */ ULONG cb , /*[out]*/ ULONG *pcbRead ) { __MPC_FUNC_ENTRY( COMMONID, "MPC::BaseStream::Read");
__MPC_FUNC_EXIT(E_NOTIMPL); }
STDMETHODIMP MPC::BaseStream::Write( /*[in] */ const void* pv , /*[in] */ ULONG cb , /*[out]*/ ULONG *pcbWritten ) { __MPC_FUNC_ENTRY( COMMONID, "MPC::BaseStream::Write");
__MPC_FUNC_EXIT(E_NOTIMPL); }
STDMETHODIMP MPC::BaseStream::Seek( /*[in] */ LARGE_INTEGER libMove , /*[in] */ DWORD dwOrigin , /*[out]*/ ULARGE_INTEGER *plibNewPosition ) { __MPC_FUNC_ENTRY( COMMONID, "MPC::BaseStream::Seek");
__MPC_FUNC_EXIT(E_NOTIMPL); }
STDMETHODIMP MPC::BaseStream::SetSize( /*[in]*/ ULARGE_INTEGER libNewSize ) { __MPC_FUNC_ENTRY( COMMONID, "MPC::BaseStream::SetSize");
__MPC_FUNC_EXIT(E_NOTIMPL); }
STDMETHODIMP MPC::BaseStream::CopyTo( /*[in] */ IStream* pstm , /*[in] */ ULARGE_INTEGER cb , /*[out]*/ ULARGE_INTEGER *pcbRead , /*[out]*/ ULARGE_INTEGER *pcbWritten ) { __MPC_FUNC_ENTRY( COMMONID, "MPC::BaseStream::CopyTo");
__MPC_FUNC_EXIT(E_NOTIMPL); }
STDMETHODIMP MPC::BaseStream::Commit( /*[in]*/ DWORD grfCommitFlags ) { __MPC_FUNC_ENTRY( COMMONID, "MPC::BaseStream::Commit");
__MPC_FUNC_EXIT(E_NOTIMPL); }
STDMETHODIMP MPC::BaseStream::Revert() { __MPC_FUNC_ENTRY( COMMONID, "MPC::BaseStream::Revert");
__MPC_FUNC_EXIT(E_NOTIMPL); }
STDMETHODIMP MPC::BaseStream::LockRegion( /*[in]*/ ULARGE_INTEGER libOffset , /*[in]*/ ULARGE_INTEGER cb , /*[in]*/ DWORD dwLockType ) { __MPC_FUNC_ENTRY( COMMONID, "MPC::BaseStream::LockRegion");
__MPC_FUNC_EXIT(E_NOTIMPL); }
STDMETHODIMP MPC::BaseStream::UnlockRegion( /*[in]*/ ULARGE_INTEGER libOffset , /*[in]*/ ULARGE_INTEGER cb , /*[in]*/ DWORD dwLockType ) { __MPC_FUNC_ENTRY( COMMONID, "MPC::BaseStream::UnlockRegion");
__MPC_FUNC_EXIT(E_NOTIMPL); }
STDMETHODIMP MPC::BaseStream::Stat( /*[out]*/ STATSTG *pstatstg , /*[in] */ DWORD grfStatFlag ) { __MPC_FUNC_ENTRY( COMMONID, "MPC::BaseStream::Stat");
__MPC_FUNC_EXIT(E_NOTIMPL); }
STDMETHODIMP MPC::BaseStream::Clone( /*[out]*/ IStream* *ppstm ) { __MPC_FUNC_ENTRY( COMMONID, "MPC::BaseStream::Clone");
__MPC_FUNC_EXIT(E_NOTIMPL); }
HRESULT MPC::BaseStream::TransferData( /*[in] */ IStream* src , /*[in] */ IStream* dst , /*[in] */ ULONG ulCount , /*[out]*/ ULONG *ulDone ) { __MPC_FUNC_ENTRY( COMMONID, "MPC::BaseStream::TransferData");
HRESULT hr; BYTE rgBuf[512]; ULONG ulTot = 0; ULONG ulRead; ULONG ulWritten; ULONG ul;
__MPC_PARAMCHECK_BEGIN(hr) __MPC_PARAMCHECK_NOTNULL(src); __MPC_PARAMCHECK_NOTNULL(dst); __MPC_PARAMCHECK_END();
while(1) { //
// Compute the amount to read on this pass (-1 == everything).
//
if(ulCount == -1) { ul = sizeof( rgBuf ); } else { ul = min( sizeof( rgBuf ), ulCount ); } if(ul == 0) break;
//
// Read and write.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, src->Read( rgBuf, ul, &ulRead )); if(hr == S_FALSE || ulRead == 0) break;
__MPC_EXIT_IF_METHOD_FAILS(hr, dst->Write( rgBuf, ulRead, &ulWritten ));
//
// Update counters.
//
if(ulCount != -1) { ulCount -= ulRead; }
ulTot += ulWritten; if(ulRead != ulWritten) { __MPC_SET_ERROR_AND_EXIT(hr, STG_E_MEDIUMFULL); } }
hr = S_OK;
__MPC_FUNC_CLEANUP;
if(ulDone) *ulDone = ulTot;
__MPC_FUNC_EXIT(hr); }
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
MPC::FileStream::FileStream() { __MPC_FUNC_ENTRY( COMMONID, "MPC::FileStream::FileStream");
// MPC::wstring m_szFile;
m_dwDesiredAccess = GENERIC_READ; // DWORD m_dwDesiredAccess;
m_dwDisposition = OPEN_EXISTING; // DWORD m_dwDisposition;
m_dwSharing = FILE_SHARE_READ | FILE_SHARE_WRITE; // DWORD m_dwSharing;
m_hfFile = NULL; // HANDLE m_hfFile;
m_fDeleteOnRelease = false; // bool m_fDeleteOnRelease;
}
MPC::FileStream::~FileStream() { __MPC_FUNC_ENTRY( COMMONID, "MPC::FileStream::~FileStream");
Close(); }
HRESULT MPC::FileStream::Close() { __MPC_FUNC_ENTRY( COMMONID, "MPC::FileStream::Close");
HRESULT hr;
if(m_hfFile) { ::CloseHandle( m_hfFile ); m_hfFile = NULL;
if(m_fDeleteOnRelease) { __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::DeleteFile( m_szFile )); } }
hr = S_OK;
__MPC_FUNC_CLEANUP;
__MPC_FUNC_EXIT(hr); }
HRESULT MPC::FileStream::Init( /*[in]*/ LPCWSTR szFile , /*[in]*/ DWORD dwDesiredAccess , /*[in]*/ DWORD dwDisposition , /*[in]*/ DWORD dwSharing , /*[in]*/ HANDLE hfFile ) { __MPC_FUNC_ENTRY( COMMONID, "MPC::FileStream::Init");
HRESULT hr;
__MPC_PARAMCHECK_BEGIN(hr) __MPC_PARAMCHECK_NOTNULL(szFile); __MPC_PARAMCHECK_END();
Close();
m_szFile = szFile; m_dwDesiredAccess = dwDesiredAccess; m_dwDisposition = dwDisposition; m_dwSharing = dwSharing;
if(hfFile) { if(::DuplicateHandle( ::GetCurrentProcess(), hfFile, ::GetCurrentProcess(), &m_hfFile, m_dwDesiredAccess, FALSE, 0 ) == FALSE) { m_hfFile = NULL; // For cleanup.
__MPC_SET_WIN32_ERROR_AND_EXIT(hr, ::GetLastError() ); } } else { __MPC_EXIT_IF_INVALID_HANDLE__CLEAN(hr, m_hfFile, ::CreateFileW( szFile, m_dwDesiredAccess, dwSharing, NULL, dwDisposition, FILE_ATTRIBUTE_NORMAL, NULL )); }
hr = S_OK;
__MPC_FUNC_CLEANUP;
__MPC_FUNC_EXIT(hr); }
HRESULT MPC::FileStream::InitForRead( /*[in]*/ LPCWSTR szFile , /*[in]*/ HANDLE hfFile ) { return Init( szFile, GENERIC_READ, OPEN_EXISTING, FILE_SHARE_READ | FILE_SHARE_WRITE, hfFile ); }
HRESULT MPC::FileStream::InitForReadWrite( /*[in]*/ LPCWSTR szFile , /*[in]*/ HANDLE hfFile ) { return Init( szFile, GENERIC_READ | GENERIC_WRITE, CREATE_ALWAYS, 0, hfFile ); }
HRESULT MPC::FileStream::InitForWrite( /*[in]*/ LPCWSTR szFile , /*[in]*/ HANDLE hfFile ) { return Init( szFile, GENERIC_WRITE, CREATE_ALWAYS, 0, hfFile ); }
HRESULT MPC::FileStream::DeleteOnRelease( /*[in]*/ bool fFlag ) { __MPC_FUNC_ENTRY( COMMONID, "MPC::FileStream::DeleteOnRelease");
m_fDeleteOnRelease = fFlag;
__MPC_FUNC_EXIT(S_OK); }
STDMETHODIMP MPC::FileStream::Read( /*[out]*/ void* pv , /*[in] */ ULONG cb , /*[out]*/ ULONG *pcbRead ) { __MPC_FUNC_ENTRY( COMMONID, "MPC::FileStream::Read");
HRESULT hr; DWORD dwRead;
if(pcbRead) *pcbRead = 0;
if(m_hfFile == NULL) __MPC_SET_ERROR_AND_EXIT(hr, STG_E_INVALIDPOINTER); if(pv == NULL) __MPC_SET_ERROR_AND_EXIT(hr, STG_E_INVALIDPOINTER);
if(::ReadFile( m_hfFile, pv, cb, &dwRead, NULL ) == FALSE) { DWORD dwRes = ::GetLastError();
if(dwRes == ERROR_ACCESS_DENIED) { __MPC_SET_ERROR_AND_EXIT(hr, STG_E_ACCESSDENIED); }
__MPC_SET_ERROR_AND_EXIT(hr, S_FALSE); } else { if(dwRead == 0 && cb != 0) { __MPC_SET_ERROR_AND_EXIT(hr, S_FALSE); } }
if(pcbRead) *pcbRead = dwRead;
hr = S_OK;
__MPC_FUNC_CLEANUP;
__MPC_FUNC_EXIT(hr); }
STDMETHODIMP MPC::FileStream::Write( /*[in] */ const void* pv , /*[in] */ ULONG cb , /*[out]*/ ULONG *pcbWritten ) { __MPC_FUNC_ENTRY( COMMONID, "MPC::FileStream::Write");
HRESULT hr; DWORD dwWritten;
if(pcbWritten) *pcbWritten = 0;
if(m_hfFile == NULL) __MPC_SET_ERROR_AND_EXIT(hr, STG_E_INVALIDPOINTER); if(pv == NULL) __MPC_SET_ERROR_AND_EXIT(hr, STG_E_INVALIDPOINTER);
if((m_dwDesiredAccess & GENERIC_WRITE) == 0) // Read-only stream.
{ __MPC_SET_ERROR_AND_EXIT(hr, STG_E_WRITEFAULT); }
if(::WriteFile( m_hfFile, pv, cb, &dwWritten, NULL ) == FALSE) { DWORD dwRes = ::GetLastError();
if(dwRes == ERROR_DISK_FULL) { __MPC_SET_ERROR_AND_EXIT(hr, STG_E_MEDIUMFULL); }
if(dwRes == ERROR_ACCESS_DENIED) { __MPC_SET_ERROR_AND_EXIT(hr, STG_E_ACCESSDENIED); }
__MPC_SET_ERROR_AND_EXIT(hr, STG_E_CANTSAVE); }
if(pcbWritten) *pcbWritten = dwWritten;
hr = S_OK;
__MPC_FUNC_CLEANUP;
__MPC_FUNC_EXIT(hr); }
STDMETHODIMP MPC::FileStream::Seek( /*[in] */ LARGE_INTEGER libMove , /*[in] */ DWORD dwOrigin , /*[out]*/ ULARGE_INTEGER *plibNewPosition ) { __MPC_FUNC_ENTRY( COMMONID, "MPC::FileStream::Seek");
HRESULT hr;
if(plibNewPosition) { plibNewPosition->HighPart = 0; plibNewPosition->LowPart = 0; }
if(m_hfFile == NULL) __MPC_SET_ERROR_AND_EXIT(hr, STG_E_INVALIDPOINTER);
switch(dwOrigin) { default : case STREAM_SEEK_CUR: dwOrigin = FILE_CURRENT; break; case STREAM_SEEK_SET: dwOrigin = FILE_BEGIN ; break; case STREAM_SEEK_END: dwOrigin = FILE_END ; break; }
if(::SetFilePointer( m_hfFile, libMove.LowPart, plibNewPosition ? (LONG*)&plibNewPosition->LowPart : NULL, dwOrigin ) == INVALID_SET_FILE_POINTER) { __MPC_SET_ERROR_AND_EXIT(hr, STG_E_INVALIDFUNCTION ); }
hr = S_OK;
__MPC_FUNC_CLEANUP;
__MPC_FUNC_EXIT(hr); }
STDMETHODIMP MPC::FileStream::Stat( /*[out]*/ STATSTG *pstatstg , /*[in] */ DWORD grfStatFlag ) { __MPC_FUNC_ENTRY( COMMONID, "MPC::FileStream::Stat");
HRESULT hr; BY_HANDLE_FILE_INFORMATION finfo;
if(pstatstg == NULL) __MPC_SET_ERROR_AND_EXIT(hr, STG_E_INVALIDPOINTER); if(m_hfFile == NULL) __MPC_SET_ERROR_AND_EXIT(hr, STG_E_INVALIDPOINTER);
if(::GetFileInformationByHandle( m_hfFile, &finfo ) == FALSE) { __MPC_SET_ERROR_AND_EXIT(hr, STG_E_ACCESSDENIED); }
pstatstg->pwcsName = NULL; pstatstg->type = STGTY_STREAM; pstatstg->cbSize.HighPart = finfo.nFileSizeHigh; pstatstg->cbSize.LowPart = finfo.nFileSizeLow; pstatstg->mtime = finfo.ftCreationTime; pstatstg->ctime = finfo.ftLastAccessTime; pstatstg->atime = finfo.ftLastWriteTime; pstatstg->grfMode = 0; pstatstg->grfLocksSupported = 0; pstatstg->clsid = CLSID_NULL; pstatstg->grfStateBits = 0; pstatstg->reserved = 0;
if(grfStatFlag != STATFLAG_NONAME) { pstatstg->pwcsName = (LPWSTR)::CoTaskMemAlloc( (m_szFile.length() + 1) * sizeof(WCHAR) ); if(pstatstg->pwcsName == NULL) { __MPC_SET_ERROR_AND_EXIT(hr, STG_E_INSUFFICIENTMEMORY); }
StringCchCopyW( pstatstg->pwcsName, m_szFile.length() + 1, m_szFile.c_str() ); }
hr = S_OK;
__MPC_FUNC_CLEANUP;
__MPC_FUNC_EXIT(hr); }
STDMETHODIMP MPC::FileStream::Clone( /*[out]*/ IStream* *ppstm ) { __MPC_FUNC_ENTRY( COMMONID, "MPC::FileStream::Clone");
HRESULT hr; MPC::CComObjectNoLock<MPC::FileStream>* pStm = NULL;
if(ppstm == NULL) __MPC_SET_ERROR_AND_EXIT(hr, STG_E_INVALIDPOINTER);
//
// Create a new stream object.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, pStm->CreateInstance( &pStm ));
//
// Initialize it with the same settings.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, pStm->Init( m_szFile.c_str(), m_dwDesiredAccess, m_dwDisposition, m_dwSharing, m_hfFile ));
//
// QI for its IStream interface.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, pStm->QueryInterface( IID_IStream, (void**)ppstm )); pStm = NULL;
hr = S_OK;
__MPC_FUNC_CLEANUP;
if(pStm) delete pStm;
__MPC_FUNC_EXIT(hr); }
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
MPC::EncryptedStream::EncryptedStream() { __MPC_FUNC_ENTRY( COMMONID, "MPC::EncryptedStream::EncryptedStream");
// CComPtr<IStream> m_pStream;
m_hCryptProv = NULL; // HCRYPTPROV m_hCryptProv;
m_hKey = NULL; // HCRYPTKEY m_hKey;
m_hHash = NULL; // HCRYPTHASH m_hHash;
// BYTE m_rgDecrypted[512];
m_dwDecryptedPos = 0; // DWORD m_dwDecryptedPos;
m_dwDecryptedLen = 0; // DWORD m_dwDecryptedLen;
}
MPC::EncryptedStream::~EncryptedStream() { __MPC_FUNC_ENTRY( COMMONID, "MPC::EncryptedStream::~EncryptedStream");
Close(); }
HRESULT MPC::EncryptedStream::Close() { __MPC_FUNC_ENTRY( COMMONID, "MPC::EncryptedStream::Close");
m_pStream.Release();
if(m_hHash) { ::CryptDestroyHash( m_hHash ); m_hHash = NULL; }
if(m_hKey) { ::CryptDestroyKey( m_hKey ); m_hKey = NULL; }
if(m_hCryptProv) { ::CryptReleaseContext( m_hCryptProv, 0 ); m_hCryptProv = NULL; }
m_dwDecryptedPos = 0; m_dwDecryptedLen = 0;
__MPC_FUNC_EXIT(S_OK); }
HRESULT MPC::EncryptedStream::Init( /*[in]*/ IStream* pStream , /*[in]*/ LPCWSTR szPassword ) { __MPC_FUNC_ENTRY( COMMONID, "MPC::EncryptedStream::Init");
HRESULT hr;
__MPC_PARAMCHECK_BEGIN(hr) __MPC_PARAMCHECK_NOTNULL(pStream); __MPC_PARAMCHECK_STRING_NOT_EMPTY(szPassword); __MPC_PARAMCHECK_END();
Close();
m_pStream = pStream;
if(!::CryptAcquireContext( &m_hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_SILENT )) { DWORD dwRes = ::GetLastError();
if(dwRes != NTE_BAD_KEYSET) { __MPC_SET_WIN32_ERROR_AND_EXIT(hr, dwRes); }
//
// Key set doesn't exist, let's create one.
//
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptAcquireContext( &m_hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET | CRYPT_SILENT )); }
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptCreateHash( m_hCryptProv, CALG_MD5, 0, 0, &m_hHash ));
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptHashData( m_hHash, (BYTE *)szPassword, sizeof(WCHAR) * wcslen( szPassword ), 0 ));
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptDeriveKey( m_hCryptProv, CALG_RC4, m_hHash, CRYPT_EXPORTABLE, &m_hKey ));
hr = S_OK;
__MPC_FUNC_CLEANUP;
if(FAILED(hr)) Close();
__MPC_FUNC_EXIT(hr); }
HRESULT MPC::EncryptedStream::Init( /*[in]*/ IStream* pStream , /*[in]*/ HCRYPTKEY hKey ) { __MPC_FUNC_ENTRY( COMMONID, "MPC::EncryptedStream::Init");
HRESULT hr;
__MPC_PARAMCHECK_BEGIN(hr) __MPC_PARAMCHECK_NOTNULL(pStream); __MPC_PARAMCHECK_NOTNULL(hKey); __MPC_PARAMCHECK_END();
Close();
m_pStream = pStream; m_hKey = hKey;
hr = S_OK;
__MPC_FUNC_CLEANUP;
if(FAILED(hr)) Close();
__MPC_FUNC_EXIT(hr); }
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP MPC::EncryptedStream::Read( /*[out]*/ void* pv , /*[in] */ ULONG cb , /*[out]*/ ULONG *pcbRead ) { __MPC_FUNC_ENTRY( COMMONID, "MPC::EncryptedStream::Read");
HRESULT hr; DWORD dwRead = 0;
if(pcbRead) *pcbRead = 0;
if(m_pStream == NULL) __MPC_SET_ERROR_AND_EXIT(hr, STG_E_INVALIDPOINTER); if(m_hKey == NULL) __MPC_SET_ERROR_AND_EXIT(hr, STG_E_INVALIDPOINTER); if(pv == NULL) __MPC_SET_ERROR_AND_EXIT(hr, STG_E_INVALIDPOINTER);
while(cb > 0) { DWORD dwCount = min( cb, (m_dwDecryptedLen - m_dwDecryptedPos)); ULONG ulRead;
if(dwCount) { ::CopyMemory( pv, &m_rgDecrypted[m_dwDecryptedPos], dwCount );
m_dwDecryptedPos += dwCount;
dwRead += dwCount; cb -= dwCount; pv = &((BYTE*)pv)[dwCount]; } else { dwCount = sizeof(m_rgDecrypted);
__MPC_EXIT_IF_METHOD_FAILS(hr, m_pStream->Read( m_rgDecrypted, dwCount, &ulRead )); if(hr == S_FALSE || ulRead == 0) break;
dwCount = ulRead;
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptDecrypt( m_hKey, 0, FALSE, 0, m_rgDecrypted, &dwCount ));
m_dwDecryptedPos = 0; m_dwDecryptedLen = dwCount; } }
if(pcbRead) *pcbRead = dwRead;
hr = S_OK;
__MPC_FUNC_CLEANUP;
__MPC_FUNC_EXIT(hr); }
STDMETHODIMP MPC::EncryptedStream::Write( /*[in] */ const void* pv , /*[in] */ ULONG cb , /*[out]*/ ULONG *pcbWritten ) { __MPC_FUNC_ENTRY( COMMONID, "MPC::EncryptedStream::Write");
HRESULT hr; DWORD dwWritten = 0;
if(pcbWritten) *pcbWritten = 0;
if(m_pStream == NULL) __MPC_SET_ERROR_AND_EXIT(hr, STG_E_INVALIDPOINTER); if(m_hKey == NULL) __MPC_SET_ERROR_AND_EXIT(hr, STG_E_INVALIDPOINTER); if(pv == NULL) __MPC_SET_ERROR_AND_EXIT(hr, STG_E_INVALIDPOINTER);
while(cb > 0) { BYTE rgTmp[512]; DWORD dwCount = min( cb, sizeof(rgTmp) / 2 ); // Let's divide by two, just in case...
ULONG ulWritten;
::CopyMemory( rgTmp, pv, dwCount );
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::CryptEncrypt( m_hKey, 0, FALSE, 0, rgTmp, &dwCount, sizeof(rgTmp) ));
__MPC_EXIT_IF_METHOD_FAILS(hr, m_pStream->Write( rgTmp, dwCount, &ulWritten ));
dwWritten += dwCount; cb -= dwCount; pv = &((BYTE*)pv)[dwCount]; }
if(pcbWritten) *pcbWritten = dwWritten;
hr = S_OK;
__MPC_FUNC_CLEANUP;
__MPC_FUNC_EXIT(hr); }
STDMETHODIMP MPC::EncryptedStream::Seek( /*[in] */ LARGE_INTEGER libMove , /*[in] */ DWORD dwOrigin , /*[out]*/ ULARGE_INTEGER *plibNewPosition ) { __MPC_FUNC_ENTRY( COMMONID, "MPC::EncryptedStream::Seek");
HRESULT hr;
hr = E_NOTIMPL;
__MPC_FUNC_EXIT(hr); }
STDMETHODIMP MPC::EncryptedStream::Stat( /*[out]*/ STATSTG *pstatstg , /*[in] */ DWORD grfStatFlag ) { __MPC_FUNC_ENTRY( COMMONID, "MPC::EncryptedStream::Stat");
HRESULT hr;
if(m_pStream == NULL) __MPC_SET_ERROR_AND_EXIT(hr, STG_E_INVALIDPOINTER);
hr = m_pStream->Stat( pstatstg, grfStatFlag );
__MPC_FUNC_CLEANUP;
__MPC_FUNC_EXIT(hr); }
STDMETHODIMP MPC::EncryptedStream::Clone( /*[out]*/ IStream* *ppstm ) { __MPC_FUNC_ENTRY( COMMONID, "MPC::EncryptedStream::Clone");
HRESULT hr;
hr = E_NOTIMPL;
__MPC_FUNC_EXIT(hr); }
|