// hwinobjbase.h
#pragma once
#ifndef __HWINOBJBASE_H__
#define __HWINOBJBASE_H__
#include "hwindef.h"
#include "hwincom.h"
#include "hwinexception.h"
#include "hwinvariant.h"
namespace harlinn
{
namespace windows
{
enum class MarshalContext : DWORD
{
Local = 0,
NoSharedMem = 1,
DifferentMachine = 2,
InProc = 3,
CrossCtx = 4
};
enum class MarshalFlags : DWORD
{
Normal = 0,
TableStrong = 1,
TableWeak = 2,
NoPing = 4
};
DEFINE_ENUM_FLAG_OPERATORS(MarshalFlags)
class Marshal : public Unknown
{
public:
typedef Unknown Base;
HARLINN_WINDOWS_COM_STANDARD_METHODS_IMPL(Marshal,Unknown,IMarshal,IUnknown)
CLSID GetUnmarshalClass( REFIID riid, void *pv, MarshalContext theDestContext, MarshalFlags flags)
{
HWIN_TRACE();
auto pInterface = GetInterface();
CLSID result;
auto hr = pInterface->GetUnmarshalClass(riid,pv,DWORD(theDestContext),nullptr,DWORD(flags),&result);
if(FAILED(hr))
{
CheckHRESULT(hr);
}
return result;
}
DWORD GetMarshalSizeMax( REFIID riid, void *pv, MarshalContext theDestContext, MarshalFlags flags)
{
HWIN_TRACE();
auto pInterface = GetInterface();
DWORD result;
auto hr = pInterface->GetMarshalSizeMax(riid,pv,DWORD(theDestContext),nullptr,DWORD(flags),&result);
if(FAILED(hr))
{
CheckHRESULT(hr);
}
return result;
}
Marshal& MarshalInterface( IStream *pStm, REFIID riid, void *pv, MarshalContext theDestContext, MarshalFlags flags)
{
HWIN_TRACE();
auto pInterface = GetInterface();
auto hr = pInterface->MarshalInterface(pStm,riid,pv,DWORD(theDestContext),nullptr,DWORD(flags));
if(FAILED(hr))
{
CheckHRESULT(hr);
}
return *this;
}
Marshal& UnmarshalInterface( IStream *pStm, REFIID riid, void **ppv)
{
HWIN_TRACE();
auto pInterface = GetInterface();
auto hr = pInterface->UnmarshalInterface(pStm,riid,ppv);
if(FAILED(hr))
{
CheckHRESULT(hr);
}
return *this;
}
Marshal& ReleaseMarshalData( IStream *pStm )
{
HWIN_TRACE();
auto pInterface = GetInterface();
auto hr = pInterface->ReleaseMarshalData(pStm);
if(FAILED(hr))
{
CheckHRESULT(hr);
}
return *this;
}
Marshal& DisconnectObject( )
{
HWIN_TRACE();
auto pInterface = GetInterface();
auto hr = pInterface->DisconnectObject( 0 );
if(FAILED(hr))
{
CheckHRESULT(hr);
}
return *this;
}
};
class Malloc : public Unknown
{
public:
typedef Unknown Base;
HARLINN_WINDOWS_COM_STANDARD_METHODS_IMPL(Malloc,Unknown,IMalloc,IUnknown)
static Malloc GetMalloc()
{
HWIN_TRACE();
IMalloc* ptr = nullptr;
auto hr = CoGetMalloc(1,&ptr);
if(FAILED(hr))
{
CheckHRESULT(hr);
}
return Malloc(ptr);
}
void* Alloc(SIZE_T numberOfBytesToAllocate)
{
HWIN_TRACE();
auto pInterface = GetInterface();
auto result = pInterface->Alloc( numberOfBytesToAllocate );
if(!result && numberOfBytesToAllocate)
{
CheckHRESULT(E_OUTOFMEMORY);
}
return result;
}
void* Realloc(void *pv,SIZE_T newMemoryBufferSize)
{
HWIN_TRACE();
auto pInterface = GetInterface();
auto result = pInterface->Realloc(pv, newMemoryBufferSize );
if(!result && newMemoryBufferSize)
{
CheckHRESULT(E_OUTOFMEMORY);
}
return result;
}
void Free(void *pv)
{
HWIN_TRACE();
auto pInterface = GetInterface();
pInterface->Free(pv);
}
SIZE_T GetSize(void *pv)
{
HWIN_TRACE();
auto pInterface = GetInterface();
auto result = pInterface->GetSize(pv);
return result;
}
int DidAlloc(void *pv)
{
HWIN_TRACE();
auto pInterface = GetInterface();
auto result = pInterface->DidAlloc(pv);
return result;
}
void HeapMinimize(void)
{
HWIN_TRACE();
auto pInterface = GetInterface();
pInterface->HeapMinimize();
}
};
class EnumUnknown : Unknown
{
public:
typedef Unknown Base;
HARLINN_WINDOWS_COM_STANDARD_METHODS_IMPL(EnumUnknown,Unknown,IEnumUnknown,IUnknown)
bool Next( Unknown& theResult )
{
HWIN_TRACE();
auto pInterface = GetInterface();
IUnknown* pElement = nullptr;
ULONG actual = 0;
auto hr = pInterface->Next(1,&pElement,&actual);
if(actual)
{
theResult.Reset(pElement);
return true;
}
return false;
}
bool Next( ULONG requestedNumberOfElements, std::vector<Unknown>& result)
{
HWIN_TRACE();
auto pInterface = GetInterface();
IUnknown** pElements = (IUnknown**)alloca(requestedNumberOfElements*sizeof(IUnknown*));
memset(pElements,0,requestedNumberOfElements*sizeof(IUnknown*));
ULONG actual = 0;
auto hr = pInterface->Next(1,pElements,&actual);
if(actual)
{
result.clear();
for(ULONG i= 0; i < actual; i++)
{
result.push_back(Unknown(pElements[i]));
}
return true;
}
return false;
}
EnumUnknown& Skip(ULONG numberOfElements)
{
HWIN_TRACE();
auto pInterface = GetInterface();
auto hr = pInterface->Skip(numberOfElements);
if(FAILED(hr))
{
CheckHRESULT(hr);
}
return *this;
}
EnumUnknown& Reset( )
{
HWIN_TRACE();
auto pInterface = GetInterface();
auto hr = pInterface->Reset();
if(FAILED(hr))
{
CheckHRESULT(hr);
}
return *this;
}
EnumUnknown Clone()
{
HWIN_TRACE();
auto pInterface = GetInterface();
IEnumUnknown* pClone = nullptr;
auto hr = pInterface->Clone(&pClone);
if(FAILED(hr))
{
CheckHRESULT(hr);
}
return EnumUnknown(pClone);
}
};
class EnumVARIANT : public Unknown
{
public:
typedef Unknown Base;
HARLINN_WINDOWS_COM_STANDARD_METHODS_IMPL(EnumVARIANT,Unknown,IEnumVARIANT,IUnknown)
bool Next( VARIANT& theResult )
{
HWIN_TRACE();
auto pInterface = GetInterface();
ULONG actual = 0;
auto hr = pInterface->Next(1,&theResult,&actual);
if(actual)
{
return true;
}
return false;
}
bool Next( ULONG requestedNumberOfElements, std::vector<Variant>& result)
{
HWIN_TRACE();
auto pInterface = GetInterface();
result.clear();
result.resize(requestedNumberOfElements);
ULONG actual = 0;
auto hr = pInterface->Next(1,result.data(),&actual);
if(actual)
{
if(result.size() != actual)
{
result.resize(actual);
}
return true;
}
return false;
}
EnumVARIANT& Skip(ULONG numberOfElements)
{
HWIN_TRACE();
auto pInterface = GetInterface();
auto hr = pInterface->Skip(numberOfElements);
if(FAILED(hr))
{
CheckHRESULT(hr);
}
return *this;
}
EnumVARIANT& Reset( )
{
HWIN_TRACE();
auto pInterface = GetInterface();
auto hr = pInterface->Reset();
if(FAILED(hr))
{
CheckHRESULT(hr);
}
return *this;
}
EnumVARIANT Clone()
{
HWIN_TRACE();
auto pInterface = GetInterface();
IEnumVARIANT* pClone = nullptr;
auto hr = pInterface->Clone(&pClone);
if(FAILED(hr))
{
CheckHRESULT(hr);
}
return EnumVARIANT(pClone);
}
};
class SequentialStream : public Unknown
{
public:
typedef Unknown Base;
HARLINN_WINDOWS_COM_STANDARD_METHODS_IMPL(SequentialStream,Unknown,ISequentialStream,IUnknown)
ULONG Read(void *pv, ULONG numberOfBytesToRead)
{
HWIN_TRACE();
auto pInterface = GetInterface();
ULONG result = 0;
auto hr = pInterface->Read(pv, numberOfBytesToRead,&result);
if(FAILED(hr))
{
CheckHRESULT(hr);
}
return result;
}
ULONG Write(const void *pv, ULONG numberOfBytesToWrite)
{
HWIN_TRACE();
auto pInterface = GetInterface();
ULONG result = 0;
auto hr = pInterface->Write(pv, numberOfBytesToWrite,&result);
if(FAILED(hr))
{
CheckHRESULT(hr);
}
return result;
}
};
class Stream : public SequentialStream
{
public:
typedef SequentialStream Base;
HARLINN_WINDOWS_COM_STANDARD_METHODS_IMPL(Stream,SequentialStream,IStream,ISequentialStream)
unsigned long long Seek( long long numberOfBytesToMove, SeekOrigin seekOrigin )
{
HWIN_TRACE();
auto pInterface = GetInterface();
ULARGE_INTEGER result;
result.QuadPart = 0;
LARGE_INTEGER btm;
btm.QuadPart = numberOfBytesToMove;
auto hr = pInterface->Seek(btm,DWORD(seekOrigin),&result);
if(FAILED(hr))
{
CheckHRESULT(hr);
}
return result.QuadPart;
}
Stream& SetSize( unsigned long long theNewSize )
{
HWIN_TRACE();
auto pInterface = GetInterface();
ULARGE_INTEGER nz;
nz.QuadPart = theNewSize;
auto hr = pInterface->SetSize(nz);
if(FAILED(hr))
{
CheckHRESULT(hr);
}
return *this;
}
Stream& CopyTo( IStream *pstm, unsigned long long numberOfBytesToCopy, unsigned long long* actualNumberOfBytesRead, unsigned long long* actualNumberOfBytesWritten)
{
HWIN_TRACE();
auto pInterface = GetInterface();
ULARGE_INTEGER nobtc,anobr,anobw;
nobtc.QuadPart = numberOfBytesToCopy;
anobr.QuadPart = 0;
anobw.QuadPart = 0;
auto hr = pInterface->CopyTo(pstm,nobtc,&anobr,&anobw);
if(FAILED(hr))
{
CheckHRESULT(hr);
}
if(actualNumberOfBytesRead)
{
*actualNumberOfBytesRead = anobr.QuadPart;
}
if(actualNumberOfBytesWritten)
{
*actualNumberOfBytesWritten = anobw.QuadPart;
}
return *this;
}
Stream& CopyTo( IStream *pstm, unsigned long long numberOfBytesToCopy, unsigned long long& actualNumberOfBytesRead, unsigned long long& actualNumberOfBytesWritten)
{
HWIN_TRACE();
auto pInterface = GetInterface();
ULARGE_INTEGER nobtc,anobr,anobw;
nobtc.QuadPart = numberOfBytesToCopy;
anobr.QuadPart = 0;
anobw.QuadPart = 0;
auto hr = pInterface->CopyTo(pstm,nobtc,&anobr,&anobw);
if(FAILED(hr))
{
CheckHRESULT(hr);
}
actualNumberOfBytesRead = anobr.QuadPart;
actualNumberOfBytesWritten = anobw.QuadPart;
return *this;
}
Stream& Commit(DWORD commitFlags = STGC_DEFAULT)
{
HWIN_TRACE();
auto pInterface = GetInterface();
auto hr = pInterface->Commit(commitFlags);
if(FAILED(hr))
{
CheckHRESULT(hr);
}
return *this;
}
Stream& Revert( )
{
HWIN_TRACE();
auto pInterface = GetInterface();
auto hr = pInterface->Revert( );
if(FAILED(hr))
{
CheckHRESULT(hr);
}
return *this;
}
Stream& LockRegion(unsigned long long offset, unsigned long long sizeOfRegion, DWORD lockType)
{
HWIN_TRACE();
auto pInterface = GetInterface();
auto hr = pInterface->LockRegion(*(ULARGE_INTEGER*)&offset, *(ULARGE_INTEGER*)&sizeOfRegion, lockType);
if(FAILED(hr))
{
CheckHRESULT(hr);
}
return *this;
}
Stream& UnlockRegion( unsigned long long offset, unsigned long long sizeOfRegion, DWORD lockType)
{
HWIN_TRACE();
auto pInterface = GetInterface();
auto hr = pInterface->UnlockRegion(*(ULARGE_INTEGER*)&offset, *(ULARGE_INTEGER*)&sizeOfRegion, lockType);
if(FAILED(hr))
{
CheckHRESULT(hr);
}
return *this;
}
Stream& Stat( STATSTG *pstatstg, DWORD grfStatFlag)
{
HWIN_TRACE();
auto pInterface = GetInterface();
auto hr = pInterface->Stat(pstatstg, grfStatFlag);
if(FAILED(hr))
{
CheckHRESULT(hr);
}
return *this;
}
Stream Clone( )
{
HWIN_TRACE();
IStream *result = nullptr;
auto pInterface = GetInterface();
auto hr = pInterface->Clone(&result);
if(FAILED(hr))
{
CheckHRESULT(hr);
}
return Stream(result);
}
Stream& WriteClassId(REFCLSID rclsid)
{
HWIN_TRACE();
auto hr = WriteClassStm(*this,rclsid);
if(FAILED(hr))
{
CheckHRESULT(hr);
}
return *this;
}
CLSID ReadClassId( )
{
HWIN_TRACE();
CLSID result = {0,};
auto hr = ReadClassStm(*this,&result);
if(FAILED(hr))
{
CheckHRESULT(hr);
}
result;
}
};
};
};
#endif // __HWINSHELL_H__