#include "stdafx.h"
#include "hwincomobject.h"
#include "hwinio.h"
namespace harlinn
{
namespace windows
{
ULONG ComObjectBase::InternalRelease( )
{
long res = InterlockedIncrement(&referenceCount);
if(!res)
{
delete this;
}
return res;
}
HWIN_EXPORT HRESULT ComStream::Read(void *pv,ULONG cb,ULONG *pcbRead)
{
HRESULT result = S_OK;
try
{
if((!pv)||(!pcbRead))
{
return STG_E_INVALIDPOINTER;
}
auto streamBase = GetStreamBase();
long long bytesRead = streamBase->Read(pv,cb);
*pcbRead = ULONG(bytesRead);
if(*pcbRead < cb)
{
result = S_FALSE;
}
}
catch(const std::exception& exception)
{
result = HRESULTFromException(exception);
}
catch(...)
{
result = E_FAIL;
}
return result;
}
HWIN_EXPORT HRESULT ComStream::Write(const void *pv,ULONG cb,ULONG *pcbWritten)
{
HRESULT result = S_OK;
try
{
if(!pv)
{
return STG_E_INVALIDPOINTER;
}
auto streamBase = GetStreamBase();
long long bytesWritten = streamBase->Write(pv,cb);
if(pcbWritten)
{
*pcbWritten = ULONG(bytesWritten);
}
if(bytesWritten < cb)
{
result = STG_E_CANTSAVE;
}
}
catch(const std::exception& exception)
{
result = HRESULTFromException(exception);
}
catch(...)
{
result = STG_E_CANTSAVE;
}
return result;
}
HWIN_EXPORT HRESULT ComStream::Seek(LARGE_INTEGER dlibMove,DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
{
HRESULT result = S_OK;
try
{
SeekOrigin seekOrigin = (SeekOrigin)dwOrigin;
auto streamBase = GetStreamBase();
long long newPosition = streamBase->Seek(dlibMove.QuadPart,seekOrigin);
if(plibNewPosition)
{
plibNewPosition->QuadPart = newPosition;
}
}
catch(const std::exception& exception)
{
result = HRESULTFromException(exception);
}
catch(...)
{
result = E_FAIL;
}
return result;
}
HWIN_EXPORT HRESULT ComStream::SetSize(ULARGE_INTEGER libNewSize)
{
HRESULT result = S_OK;
try
{
long long newSize = (long long)libNewSize.QuadPart;
auto streamBase = GetStreamBase();
streamBase->SetSize(newSize);
long long actualNewSize = streamBase->Size();
if(newSize != actualNewSize)
{
result = STG_E_INVALIDFUNCTION;
}
}
catch(const std::exception& exception)
{
result = HRESULTFromException(exception);
}
catch(...)
{
result = E_FAIL;
}
return result;
}
HWIN_EXPORT HRESULT ComStream::CopyTo( IStream *pstm,ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
{
HRESULT result = S_OK;
try
{
if(!pstm)
{
return STG_E_INVALIDPOINTER;
}
auto streamBase = GetStreamBase();
unsigned long long totalBytesRead = 0;
unsigned long long totalBytesWritten = 0;
unsigned long long bytesRead = 0;
unsigned long bytesWritten = 0;
char buffer[16*1024];
while(totalBytesWritten < cb.QuadPart)
{
unsigned long long remainingBytes = cb.QuadPart - totalBytesWritten;
unsigned long bytesToCopy = (unsigned long)std::min(UINT64(sizeof(buffer)),remainingBytes);
bytesRead = streamBase->Read(buffer,bytesToCopy);
auto hr = pstm->Write(buffer,ULONG(bytesRead),&bytesWritten);
totalBytesRead += bytesRead;
totalBytesWritten += bytesWritten;
if(FAILED(hr))
{
return hr;
}
if((bytesRead == 0)||(bytesWritten == 0))
{
break;
}
}
if(pcbRead)
{
pcbRead->QuadPart = totalBytesRead;
}
if(pcbWritten)
{
pcbWritten->QuadPart = totalBytesWritten;
}
}
catch(const std::exception& exception)
{
result = HRESULTFromException(exception);
}
catch(...)
{
result = E_FAIL;
}
return result;
}
HWIN_EXPORT HRESULT ComStream::Commit(DWORD grfCommitFlags)
{
HRESULT result = S_OK;
try
{
auto streamBase = GetStreamBase();
streamBase->Flush();
}
catch(const std::exception& exception)
{
result = HRESULTFromException(exception);
}
catch(...)
{
result = E_FAIL;
}
return result;
}
HWIN_EXPORT HRESULT ComStream::Revert( void )
{
HRESULT result = S_OK;
return result;
}
HWIN_EXPORT HRESULT ComStream::LockRegion( ULARGE_INTEGER libOffset,ULARGE_INTEGER cb,DWORD dwLockType)
{
HRESULT result = STG_E_INVALIDFUNCTION;
return result;
}
HWIN_EXPORT HRESULT ComStream::UnlockRegion( ULARGE_INTEGER libOffset,ULARGE_INTEGER cb,DWORD dwLockType)
{
HRESULT result = STG_E_INVALIDFUNCTION;
return result;
}
HWIN_EXPORT HRESULT ComStream::Stat( STATSTG *pstatstg,DWORD grfStatFlag )
{
HRESULT result = S_OK;
try
{
if(!pstatstg)
{
return STG_E_INVALIDPOINTER;
}
auto streamBase = GetStreamBase();
memset(pstatstg,0,sizeof(STATSTG));
pstatstg->type = STGTY_STREAM;
pstatstg->cbSize.QuadPart = streamBase->Size();
GetSystemTimeAsFileTime(&pstatstg->mtime);
pstatstg->ctime = pstatstg->mtime;
pstatstg->atime = pstatstg->mtime;
}
catch(const std::exception& exception)
{
result = HRESULTFromException(exception);
}
catch(...)
{
result = E_FAIL;
}
return result;
}
HWIN_EXPORT HRESULT ComStream::Clone( IStream **ppstm )
{
HRESULT result = S_OK;
try
{
if(!ppstm)
{
return STG_E_INVALIDPOINTER;
}
auto streamBase = GetStreamBase();
auto clone = streamBase->Clone();
result = clone->QueryInterface(IID_IStream,(void**)ppstm);
}
catch(const std::exception& exception)
{
result = HRESULTFromException(exception);
}
catch(...)
{
result = E_FAIL;
}
return result;
}
};
};