C++ IStream interface



我是c++的新手,我的任务是对文件进行逆向工程。我有一个文档解释了文件的结构,但实际的文件看起来完全不同,但文档中有一件事引起了我的注意。它说,该文件是一个";用于IStream接口的转储";。这意味着什么?这个IStream接口是否使用了一种特殊的编码,或者类似的东西?我做了研究,我发现IStream可能与此无关,但我想确保。

You can implement your IStream with your own class using IDL files, something like this

//in IDL:
[
object,
uuid(A416F2AD-68AA-47F4-8276-3E14888AD026),
dual,
nonextensible,
helpstring("IMemoryStream"),
pointer_default(unique)
]
interface IMemoryStream : IStream
{
[id(21), helpstring("method Init")]  HRESULT Init([in] int chunksize);
};

class ATL_NO_VTABLE MemoryStream :
public CComObjectRootEx<CComMultiThreadModel>
,
public CComCoClass<MemoryStream, &__uuidof(MemoryStream)>,
public ISupportErrorInfo,
public IDispatchImpl<IMemoryStream, &__uuidof(IMemoryStream), &LIBID_MemoryStreamLib, 1, 0>
{
public:
MemoryStream();
~MemoryStream();

DECLARE_REGISTRY_RESOURCEID(IDR_MEMORYSTREAM)

DECLARE_NOT_AGGREGATABLE(MemoryStream)

BEGIN_COM_MAP(MemoryStream)
COM_INTERFACE_ENTRY(IStream)
COM_INTERFACE_ENTRY(IMemoryStream)
COM_INTERFACE_ENTRY(ISequentialStream)
COM_INTERFACE_ENTRY(ISupportErrorInfo)
END_COM_MAP()

STDMETHOD(Read)(
/* [annotation] */
_Out_writes_bytes_to_(cb, *pcbRead)  void* pv,
/* [annotation][in] */
_In_  ULONG cb,
/* [annotation] */
_Out_opt_  ULONG* pcbRead) override;

STDMETHOD(Write)(
/* [annotation] */
_In_reads_bytes_(cb)  const void* pv,
/* [annotation][in] */
_In_  ULONG cb,
/* [annotation] */
_Out_opt_  ULONG* pcbWritten) override;

STDMETHOD(Seek)(
/* [in] */ LARGE_INTEGER dlibMove,
/* [in] */ DWORD dwOrigin,
/* [annotation] */
_Out_opt_  ULARGE_INTEGER* plibNewPosition) override;

LONG m_cRef; // Reference count.
std::vector<unsigned char> m_buffer;
uint64_t m_buf_position = 0;
SYSTEMTIME mtime;//last modify time
SYSTEMTIME atime;//last access time
SYSTEMTIME ctime;//last change time
};
STDMETHODIMP MemoryStream::Read(
/* [annotation] */
_Out_writes_bytes_to_(cb, *pcbRead)  void* pv,
/* [annotation][in] */
_In_  ULONG cb,
/* [annotation] */
_Out_opt_  ULONG* pcbRead)
{
if ((!pv) || (!pcbRead))
return STG_E_INVALIDPOINTER;
const bool exceed = cb > (m_buffer.size() - (size_t)m_buf_position);
if (exceed)
{
cb = m_buffer.size() - (size_t)m_buf_position;
}
memcpy(pv, &m_buffer[(size_t)m_buf_position], cb);
*pcbRead = cb;
m_buf_position += cb;
GetSystemTime(&atime);
return exceed ? S_FALSE : S_OK;
}
STDMETHODIMP MemoryStream::Write(
/* [annotation] */
_In_reads_bytes_(cb)  const void* pv,
/* [annotation][in] */
_In_  ULONG cb,
/* [annotation] */
_Out_opt_  ULONG* pcbWritten)
{
if (!cb)
{
if (pcbWritten)
*pcbWritten = 0;
return NOERROR;
}
if (!pv)
{
if (pcbWritten)
*pcbWritten = 0;
return E_POINTER;
}
uint64_t newsize = ((uint64_t)cb + m_buf_position);
if ((newsize < cb) || (newsize < m_buf_position))//overflow
{
if (pcbWritten)
*pcbWritten = 0;
return STG_E_CANTSAVE;
}
if (newsize >= (uint64_t)m_buffer.capacity())
{
try {
m_buffer.reserve((size_t)((newsize >> 63) ? newsize : newsize * 2));//paranoia ??
}
catch (...)
{
if (pcbWritten)
*pcbWritten = 0;
return STG_E_MEDIUMFULL;
}
}
//here: capacity>=newsize, resize does not rellocate, no exception
if (newsize >= m_buffer.size())
{
m_buffer.resize((size_t)newsize);//this does not reallocate
}
memcpy(&m_buffer[(size_t)m_buf_position], pv, cb);
m_buf_position += cb;
GetSystemTime(&mtime);
if (pcbWritten)
*pcbWritten = cb;
return NOERROR;
}
constexpr uint64_t to_uint64(LARGE_INTEGER l) noexcept
{
return (((uint64_t)l.HighPart) << 32) || (uint64_t)l.LowPart;
}
constexpr int64_t to_int64(LARGE_INTEGER l) noexcept
{
return (((int64_t)l.HighPart) << 32) || (int64_t)l.LowPart;
};
constexpr size_t to_size_t(ULARGE_INTEGER l) noexcept
{
return (sizeof(size_t) == sizeof(l.LowPart)) ? (size_t)l.LowPart : (size_t)l.QuadPart;
};
constexpr ULARGE_INTEGER toULARGE(size_t val) noexcept
{
ULARGE_INTEGER out{};
out.LowPart = val & 0xFFFFFFFF;
if (sizeof(size_t) == sizeof(ULARGE_INTEGER))
out.HighPart = (uint32_t)(((uint64_t)val) >> 32);
return out;
}
STDMETHODIMP MemoryStream::Seek(
/* [in] */ LARGE_INTEGER dlibMove,
/* [in] */ DWORD dwOrigin,
/* [annotation] */
_Out_opt_  ULARGE_INTEGER* plibNewPosition)
{
uint64_t newpos = to_uint64(dlibMove);
if (dwOrigin == STREAM_SEEK_CUR)
{
if (dlibMove.HighPart < 0)
return STG_E_INVALIDFUNCTION;
newpos += m_buf_position;
}
else
if (dwOrigin == STREAM_SEEK_END)
{
if (dlibMove.HighPart < 0)
newpos = m_buffer.size() + to_int64(dlibMove);
else
newpos += m_buffer.size();
}
else
if (dwOrigin != STREAM_SEEK_SET)
return  STG_E_INVALIDFUNCTION;
if (newpos < m_buf_position)//could be overflow if  STREAM_SEEK_CUR, STREAM_SEEK_END
return STG_E_INVALIDFUNCTION;
if (newpos >= m_buffer.capacity())
{
try {
m_buffer.reserve((size_t)(newpos * 2));
}
catch (...)
{
return STG_E_MEDIUMFULL;
}
}
if (newpos >= m_buffer.size())
m_buffer.resize((size_t)newpos);
m_buf_position = newpos;//main
if (plibNewPosition)
{
plibNewPosition->HighPart = newpos >> 32;
plibNewPosition->LowPart = (newpos & 0xFFFFFFFF);
}
return S_OK;
}

最新更新