159 lines
4.8 KiB
C++
159 lines
4.8 KiB
C++
|
//+---------------------------------------------------------------------
|
|||
|
//
|
|||
|
// File: stgutils.hxx
|
|||
|
//
|
|||
|
// Contents: IStorage and IStream Helper functions
|
|||
|
//
|
|||
|
//----------------------------------------------------------------------
|
|||
|
|
|||
|
#include "headers.hxx"
|
|||
|
#pragma hdrstop
|
|||
|
|
|||
|
//+---------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: GetMonikerDisplayName
|
|||
|
//
|
|||
|
// Synopsis: Retrieves the display name of a moniker
|
|||
|
//
|
|||
|
// Arguments: [pmk] -- the moniker for which the display name is requested
|
|||
|
// [ppstr] -- the place where the display name is returned
|
|||
|
//
|
|||
|
// Returns: Success iff the display name could be retrieved
|
|||
|
//
|
|||
|
// Notes: The display name string is allocated using the task allocator
|
|||
|
// and should be freed by the same.
|
|||
|
//
|
|||
|
//----------------------------------------------------------------
|
|||
|
|
|||
|
HRESULT
|
|||
|
GetMonikerDisplayName(LPMONIKER pmk, LPOLESTR FAR* ppstr)
|
|||
|
{
|
|||
|
HRESULT r;
|
|||
|
LPBC pbc;
|
|||
|
if (OK(r = CreateBindCtx(0, &pbc)))
|
|||
|
{
|
|||
|
r = pmk->GetDisplayName(pbc, NULL, ppstr);
|
|||
|
pbc->Release();
|
|||
|
}
|
|||
|
return r;
|
|||
|
}
|
|||
|
|
|||
|
//+---------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: CreateStorageOnHGlobal
|
|||
|
//
|
|||
|
// Synopsis: Creates an IStorage on a global memory handle
|
|||
|
//
|
|||
|
// Arguments: [hgbl] -- memory handle to create storage on
|
|||
|
// [ppStg] -- where the storage is returned
|
|||
|
//
|
|||
|
// Returns: Success iff the storage could be successfully created
|
|||
|
// on the memory handle.
|
|||
|
//
|
|||
|
// Notes: This helper function combines CreateILockBytesOnHGlobal
|
|||
|
// and StgCreateDocfileOnILockBytes. hgbl may be NULL in
|
|||
|
// which case a global memory handle will be automatically
|
|||
|
// allocated.
|
|||
|
//
|
|||
|
//----------------------------------------------------------------
|
|||
|
|
|||
|
HRESULT
|
|||
|
CreateStorageOnHGlobal(HGLOBAL hgbl, LPSTORAGE FAR* ppStg)
|
|||
|
{
|
|||
|
HRESULT r;
|
|||
|
LPLOCKBYTES pLockBytes;
|
|||
|
if (OK(r = CreateILockBytesOnHGlobal(hgbl, TRUE, &pLockBytes)))
|
|||
|
{
|
|||
|
//REVIEW: should be use STGM_DELETEONRELEASE when hgbl == NULL?
|
|||
|
r = StgCreateDocfileOnILockBytes(pLockBytes,
|
|||
|
STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, ppStg);
|
|||
|
pLockBytes->Release();
|
|||
|
}
|
|||
|
return r;
|
|||
|
}
|
|||
|
|
|||
|
//+---------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: ConvertToMemoryStream
|
|||
|
//
|
|||
|
// Synopsis: Takes a stream and produces an equivalent stream
|
|||
|
// stored in memory for faster individual reads
|
|||
|
//
|
|||
|
// Arguments: [pStrmFrom] -- the stream to convert
|
|||
|
//
|
|||
|
// Returns: An equivalent stream
|
|||
|
//
|
|||
|
// Notes: Any failure in creating the memory stream will result in
|
|||
|
// the original stream, pStrmFrom, being returned.
|
|||
|
// Hence the caller should assume the stream passed in has
|
|||
|
// been released and should release the stream returned
|
|||
|
// after it has finished using it.
|
|||
|
//
|
|||
|
//----------------------------------------------------------------
|
|||
|
|
|||
|
LPSTREAM
|
|||
|
ConvertToMemoryStream(LPSTREAM pStrmFrom)
|
|||
|
{
|
|||
|
//REVIEW: perhaps we should use the IStream::CopyTo function
|
|||
|
// instead of doing the read manually!
|
|||
|
HRESULT r;
|
|||
|
LPSTREAM pStrm = NULL;
|
|||
|
STATSTG statstg;
|
|||
|
|
|||
|
if (OK(r = pStrmFrom->Stat(&statstg, STATFLAG_NONAME)))
|
|||
|
{
|
|||
|
if (statstg.cbSize.HighPart != 0)
|
|||
|
{
|
|||
|
DOUT(TEXT("o2base/stdils/ConvertToMemoryStream E_FAIL\r\n"));
|
|||
|
r = E_FAIL;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
HGLOBAL hgbl = GlobalAlloc(GMEM_SHARE, statstg.cbSize.LowPart);
|
|||
|
if (hgbl == NULL)
|
|||
|
{
|
|||
|
DOUT(TEXT("o2base/stgutils/ConvertToMemoryStream failed\r\n"));
|
|||
|
r = E_OUTOFMEMORY;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
LPVOID pv = GlobalLock(hgbl);
|
|||
|
if (pv == NULL)
|
|||
|
{
|
|||
|
DOUT(TEXT("o2base/stdils/ConvertToMemoryStream E_FAIL(2)\r\n"));
|
|||
|
r = E_FAIL;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
r = pStrmFrom->Read(pv, statstg.cbSize.LowPart, NULL);
|
|||
|
GlobalUnlock(hgbl);
|
|||
|
if (OK(r))
|
|||
|
{
|
|||
|
if (OK(r = CreateStreamOnHGlobal(hgbl, TRUE, &pStrm)))
|
|||
|
{
|
|||
|
pStrm->SetSize(statstg.cbSize);
|
|||
|
pStrmFrom->Release();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
DOUT(TEXT("o2base/stdils/ConvertToMemoryStream CreateStreamOnHGlobal Failed!\r\n"));
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
if (!OK(r))
|
|||
|
{
|
|||
|
GlobalFree(hgbl);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (!OK(r))
|
|||
|
{
|
|||
|
pStrm = pStrmFrom;
|
|||
|
}
|
|||
|
|
|||
|
return pStrm;
|
|||
|
}
|
|||
|
|
|||
|
|