You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
991 lines
25 KiB
991 lines
25 KiB
/*++
|
|
|
|
Copyright (C) Microsoft Corporation 1999
|
|
|
|
Module Name:
|
|
|
|
ByteBuffer
|
|
|
|
Abstract:
|
|
|
|
The IByteBuffer interface is provided to read, write and manage stream
|
|
objects. This object essentially is a wrapper for the IStream object.
|
|
|
|
Author:
|
|
|
|
Doug Barlow (dbarlow) 6/16/1999
|
|
|
|
Notes:
|
|
|
|
This is a rewrite of the original code by Mike Gallagher and Chris Dudley.
|
|
|
|
--*/
|
|
|
|
#ifndef WIN32_LEAN_AND_MEAN
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#endif
|
|
#include "stdafx.h"
|
|
#include "ByteBuffer.h"
|
|
#include "Conversion.h"
|
|
#define SetXL(xl, low, high) do { xl.LowPart = low; xl.HighPart = high; } while (0)
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CByteBuffer
|
|
|
|
STDMETHODIMP
|
|
CByteBuffer::get_Stream(
|
|
/* [retval][out] */ LPSTREAM __RPC_FAR *ppStream)
|
|
{
|
|
HRESULT hReturn = S_OK;
|
|
|
|
try
|
|
{
|
|
*ppStream = Stream();
|
|
(*ppStream)->AddRef();
|
|
}
|
|
|
|
catch (HRESULT hError)
|
|
{
|
|
hReturn = hError;
|
|
}
|
|
catch (...)
|
|
{
|
|
hReturn = E_INVALIDARG;
|
|
}
|
|
|
|
return hReturn;
|
|
}
|
|
|
|
STDMETHODIMP CByteBuffer::put_Stream(
|
|
/* [in] */ LPSTREAM pStream)
|
|
{
|
|
HRESULT hReturn = S_OK;
|
|
LPSTREAM pOldStream = m_pStreamBuf;
|
|
|
|
try
|
|
{
|
|
pStream->AddRef();
|
|
m_pStreamBuf = pStream;
|
|
if (NULL != pOldStream)
|
|
pOldStream->Release();
|
|
}
|
|
|
|
catch (HRESULT hError)
|
|
{
|
|
hReturn = hError;
|
|
}
|
|
catch (...)
|
|
{
|
|
hReturn = E_INVALIDARG;
|
|
}
|
|
|
|
return hReturn;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Clone:
|
|
|
|
The Clone method creates a new object with its own seek pointer that
|
|
references the same bytes as the original IByteBuffer object.
|
|
|
|
Arguments:
|
|
|
|
ppByteBuffer [out] When successful, points to the location of an
|
|
IByteBuffer pointer to the new stream object. If an error occurs, this
|
|
parameter is NULL.
|
|
|
|
Return Value:
|
|
|
|
The return value is an HRESULT. A value of S_OK indicates the call was
|
|
successful.
|
|
|
|
Remarks:
|
|
|
|
This method creates a new stream object for accessing the same bytes but
|
|
using a separate seek pointer. The new stream object sees the same data as
|
|
the source stream object. Changes written to one object are immediately
|
|
visible in the other. Range locking is shared between the stream objects.
|
|
|
|
The initial setting of the seek pointer in the cloned stream instance is
|
|
the same as the current setting of the seek pointer in the original stream
|
|
at the time of the clone operation.
|
|
|
|
Author:
|
|
|
|
Doug Barlow (dbarlow) 6/16/1999
|
|
|
|
--*/
|
|
#undef __SUBROUTINE__
|
|
#define __SUBROUTINE__ TEXT("CByteBuffer::Clone")
|
|
|
|
STDMETHODIMP
|
|
CByteBuffer::Clone(
|
|
/* [out][in] */ LPBYTEBUFFER __RPC_FAR *ppByteBuffer)
|
|
{
|
|
HRESULT hReturn = S_OK;
|
|
CByteBuffer *pNewBuf = NULL;
|
|
LPSTREAM pNewStream = NULL;
|
|
|
|
try
|
|
{
|
|
HRESULT hr;
|
|
|
|
*ppByteBuffer = NULL;
|
|
pNewBuf = NewByteBuffer();
|
|
if (NULL == pNewBuf)
|
|
throw (HRESULT)E_OUTOFMEMORY;
|
|
hr = Stream()->Clone(&pNewStream);
|
|
if (FAILED(hr))
|
|
throw hr;
|
|
hr = pNewBuf->put_Stream(pNewStream);
|
|
if (FAILED(hr))
|
|
throw hr;
|
|
pNewStream->Release();
|
|
pNewStream = NULL;
|
|
*ppByteBuffer = pNewBuf;
|
|
pNewBuf = NULL;
|
|
}
|
|
|
|
catch (HRESULT hError)
|
|
{
|
|
hReturn = hError;
|
|
}
|
|
catch (...)
|
|
{
|
|
hReturn = E_INVALIDARG;
|
|
}
|
|
|
|
if (NULL != pNewBuf)
|
|
pNewBuf->Release();
|
|
if (NULL != pNewStream)
|
|
pNewStream->Release();
|
|
return hReturn;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Commit:
|
|
|
|
The Commit method ensures that any changes made to an object open in
|
|
transacted mode are reflected in the parent storage.
|
|
|
|
Arguments:
|
|
|
|
grfCommitFlags [in] Controls how the changes for the stream object are
|
|
committed. See the STGC enumeration for a definition of these values.
|
|
|
|
Return Value:
|
|
|
|
The return value is an HRESULT. A value of S_OK indicates the call was
|
|
successful.
|
|
|
|
Remarks:
|
|
|
|
This method ensures that changes to a stream object opened in transacted
|
|
mode are reflected in the parent storage. Changes that have been made to
|
|
the stream since it was opened or last committed are reflected to the
|
|
parent storage object. If the parent is opened in transacted mode, the
|
|
parent may still revert at a later time rolling back the changes to this
|
|
stream object. The compound file implementation does not support opening
|
|
streams in transacted mode, so this method has very little effect other
|
|
than to flush memory buffers.
|
|
|
|
Author:
|
|
|
|
Doug Barlow (dbarlow) 6/16/1999
|
|
|
|
--*/
|
|
#undef __SUBROUTINE__
|
|
#define __SUBROUTINE__ TEXT("CByteBuffer::Commit")
|
|
|
|
STDMETHODIMP
|
|
CByteBuffer::Commit(
|
|
/* [in] */ LONG grfCommitFlags)
|
|
{
|
|
HRESULT hReturn = S_OK;
|
|
|
|
try
|
|
{
|
|
hReturn = Stream()->Commit(grfCommitFlags);
|
|
}
|
|
|
|
catch (HRESULT hError)
|
|
{
|
|
hReturn = hError;
|
|
}
|
|
catch (...)
|
|
{
|
|
hReturn = E_INVALIDARG;
|
|
}
|
|
|
|
return hReturn;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
CopyTo:
|
|
|
|
The CopyTo method copies a specified number of bytes from the current seek
|
|
pointer in the object to the current seek pointer in another object.
|
|
|
|
Arguments:
|
|
|
|
pByteBuffer [in] Points to the destination stream. The stream pointed to by
|
|
pByteBuffer can be a new stream or a clone of the source stream.
|
|
|
|
cb [in] Specifies the number of bytes to copy from the source stream.
|
|
|
|
pcbRead [out] Pointer to the location where this method writes the actual
|
|
number of bytes read from the source. You can set this pointer to NULL
|
|
to indicate that you are not interested in this value. In this case,
|
|
this method does not provide the actual number of bytes read.
|
|
|
|
pcbWritten [out] Pointer to the location where this method writes the
|
|
actual number of bytes written to the destination. You can set this
|
|
pointer to NULL to indicate that you are not interested in this value.
|
|
In this case, this method does not provide the actual number of bytes
|
|
written.
|
|
|
|
Return Value:
|
|
|
|
The return value is an HRESULT. A value of S_OK indicates the call was
|
|
successful.
|
|
|
|
Remarks:
|
|
|
|
This method copies the specified bytes from one stream to another. It can
|
|
also be used to copy a stream to itself. The seek pointer in each stream
|
|
instance is adjusted for the number of bytes read or written.
|
|
|
|
Author:
|
|
|
|
Doug Barlow (dbarlow) 6/16/1999
|
|
|
|
--*/
|
|
#undef __SUBROUTINE__
|
|
#define __SUBROUTINE__ TEXT("CByteBuffer::CopyTo")
|
|
|
|
STDMETHODIMP
|
|
CByteBuffer::CopyTo(
|
|
/* [out][in] */ LPBYTEBUFFER __RPC_FAR *ppByteBuffer,
|
|
/* [in] */ LONG cb,
|
|
/* [defaultvalue][out][in] */ LONG __RPC_FAR *pcbRead,
|
|
/* [defaultvalue][out][in] */ LONG __RPC_FAR *pcbWritten)
|
|
{
|
|
HRESULT hReturn = S_OK;
|
|
CByteBuffer *pMyBuffer = NULL;
|
|
LPSTREAM pStream = NULL;
|
|
|
|
try
|
|
{
|
|
HRESULT hr;
|
|
ULARGE_INTEGER xulcb, xulRead, xulWritten;
|
|
|
|
if (NULL == *ppByteBuffer)
|
|
{
|
|
*ppByteBuffer = pMyBuffer = NewByteBuffer();
|
|
if (NULL == *ppByteBuffer)
|
|
throw (HRESULT)E_OUTOFMEMORY;
|
|
}
|
|
|
|
hr = (*ppByteBuffer)->get_Stream(&pStream);
|
|
if (FAILED(hr))
|
|
throw hr;
|
|
SetXL(xulcb, cb, 0);
|
|
SetXL(xulRead, 0, 0);
|
|
SetXL(xulWritten, 0, 0);
|
|
hr = Stream()->CopyTo(pStream, xulcb, &xulRead, &xulWritten);
|
|
if (FAILED(hr))
|
|
throw hr;
|
|
pStream->Release();
|
|
pStream = NULL;
|
|
if (NULL != pcbRead)
|
|
*pcbRead = xulRead.LowPart;
|
|
if (NULL != pcbWritten)
|
|
*pcbWritten = xulWritten.LowPart;
|
|
pMyBuffer = NULL;
|
|
}
|
|
|
|
catch (HRESULT hError)
|
|
{
|
|
hReturn = hError;
|
|
}
|
|
catch (...)
|
|
{
|
|
hReturn = E_INVALIDARG;
|
|
}
|
|
|
|
if (NULL != pMyBuffer)
|
|
{
|
|
pMyBuffer->Release();
|
|
*ppByteBuffer = NULL;
|
|
}
|
|
if (NULL != pStream)
|
|
pStream->Release();
|
|
return hReturn;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Initialize:
|
|
|
|
The Initialize method prepares the IByteBuffer object for use. This method
|
|
must be called prior to calling any other methods in the IByteBuffer
|
|
interface.
|
|
|
|
Arguments:
|
|
|
|
lSize - The initial size in bytes of the data the stream is to contain.
|
|
|
|
pData - If not NULL, the initial data to write to the stream.
|
|
|
|
Return Value:
|
|
|
|
The return value is an HRESULT. A value of S_OK indicates the call was
|
|
successful.
|
|
|
|
Remarks:
|
|
|
|
When using a new IByteBuffer stream, call this method prior to using any of
|
|
the other IByteBuffer methods.
|
|
|
|
Author:
|
|
|
|
Doug Barlow (dbarlow) 6/16/1999
|
|
|
|
--*/
|
|
#undef __SUBROUTINE__
|
|
#define __SUBROUTINE__ TEXT("CByteBuffer::Initialize")
|
|
|
|
STDMETHODIMP
|
|
CByteBuffer::Initialize(
|
|
/* [defaultvalue][in] */ LONG lSize,
|
|
/* [defaultvalue][in] */ BYTE __RPC_FAR *pData)
|
|
{
|
|
HRESULT hReturn = S_OK;
|
|
|
|
try
|
|
{
|
|
HRESULT hr;
|
|
ULARGE_INTEGER xul;
|
|
LARGE_INTEGER xl;
|
|
|
|
SetXL(xul, 0, 0);
|
|
SetXL(xl, 0, 0);
|
|
|
|
hr = Stream()->SetSize(xul);
|
|
if (FAILED(hr))
|
|
throw hr;
|
|
hr = Stream()->Seek(xl, STREAM_SEEK_SET, NULL);
|
|
if (FAILED(hr))
|
|
throw hr;
|
|
if ((0 != lSize) && (NULL != pData))
|
|
{
|
|
hr = Stream()->Write(pData, lSize, NULL);
|
|
if (FAILED(hr))
|
|
throw hr;
|
|
}
|
|
}
|
|
|
|
catch (HRESULT hError)
|
|
{
|
|
hReturn = hError;
|
|
}
|
|
catch (...)
|
|
{
|
|
hReturn = E_INVALIDARG;
|
|
}
|
|
|
|
return hReturn;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
LockRegion:
|
|
|
|
The LockRegion method restricts access to a specified range of bytes in the
|
|
buffer object.
|
|
|
|
Arguments:
|
|
|
|
libOffset [in] Integer that specifies the byte offset for the beginning of
|
|
the range.
|
|
|
|
cb [in] Integer that specifies the length of the range, in bytes, to be
|
|
restricted.
|
|
|
|
dwLockType [in] Specifies the restrictions being requested on accessing the
|
|
range.
|
|
|
|
Return Value:
|
|
|
|
The return value is an HRESULT. A value of S_OK indicates the call was
|
|
successful.
|
|
|
|
Remarks:
|
|
|
|
The byte range can extend past the current end of the stream. Locking
|
|
beyond the end of a stream is useful as a method of communication between
|
|
different instances of the stream without changing data that is actually
|
|
part of the stream.
|
|
|
|
Three types of locking can be supported: locking to exclude other writers,
|
|
locking to exclude other readers or writers, and locking that allows only
|
|
one requestor to obtain a lock on the given range, which is usually an
|
|
alias for one of the other two lock types. A given stream instance might
|
|
support either of the first two types, or both. The lock type is specified
|
|
by dwLockType, using a value from the LOCKTYPE enumeration.
|
|
|
|
Any region locked with IByteBuffer::LockRegion must later be explicitly
|
|
unlocked by calling IByteBuffer::UnlockRegion with exactly the same values
|
|
for the libOffset, cb, and dwLockType parameters. The region must be
|
|
unlocked before the stream is released. Two adjacent regions cannot be
|
|
locked separately and then unlocked with a single unlock call.
|
|
|
|
Author:
|
|
|
|
Doug Barlow (dbarlow) 6/16/1999
|
|
|
|
--*/
|
|
#undef __SUBROUTINE__
|
|
#define __SUBROUTINE__ TEXT("CByteBuffer::LockRegion")
|
|
|
|
STDMETHODIMP
|
|
CByteBuffer::LockRegion(
|
|
/* [in] */ LONG libOffset,
|
|
/* [in] */ LONG cb,
|
|
/* [in] */ LONG dwLockType)
|
|
{
|
|
HRESULT hReturn = S_OK;
|
|
|
|
try
|
|
{
|
|
ULARGE_INTEGER xulOffset, xulcb;
|
|
|
|
SetXL(xulOffset, libOffset, 0);
|
|
SetXL(xulcb, cb, 0);
|
|
hReturn = Stream()->LockRegion(xulOffset, xulcb, dwLockType);
|
|
}
|
|
|
|
catch (HRESULT hError)
|
|
{
|
|
hReturn = hError;
|
|
}
|
|
catch (...)
|
|
{
|
|
hReturn = E_INVALIDARG;
|
|
}
|
|
|
|
return hReturn;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Read:
|
|
|
|
The Read method reads a specified number of bytes from the buffer object
|
|
into memory starting at the current seek pointer.
|
|
|
|
Arguments:
|
|
|
|
pByte [out] Points to the buffer into which the stream data is read. If an
|
|
error occurs, this value is NULL.
|
|
|
|
cb [in] Specifies the number of bytes of data to attempt to read from the
|
|
stream object.
|
|
|
|
pcbRead [out] Address of a LONG variable that receives the actual number of
|
|
bytes read from the stream object. You can set this pointer to NULL to
|
|
indicate that you are not interested in this value. In this case, this
|
|
method does not provide the actual number of bytes read.
|
|
|
|
Return Value:
|
|
|
|
The return value is an HRESULT. A value of S_OK indicates the call was
|
|
successful.
|
|
|
|
Remarks:
|
|
|
|
This method reads bytes from this stream object into memory. The stream
|
|
object must be opened in STGM_READ mode. This method adjusts the seek
|
|
pointer by the actual number of bytes read.
|
|
|
|
The number of bytes actually read is also returned in the pcbRead
|
|
parameter.
|
|
|
|
Notes to Callers
|
|
|
|
The actual number of bytes read can be fewer than the number of bytes
|
|
requested if an error occurs or if the end of the stream is reached during
|
|
the read operation.
|
|
|
|
Some implementations might return an error if the end of the stream is
|
|
reached during the read. You must be prepared to deal with the error
|
|
return or S_OK return values on end of stream reads.
|
|
|
|
Author:
|
|
|
|
Doug Barlow (dbarlow) 6/16/1999
|
|
|
|
--*/
|
|
#undef __SUBROUTINE__
|
|
#define __SUBROUTINE__ TEXT("CByteBuffer::Read")
|
|
|
|
STDMETHODIMP
|
|
CByteBuffer::Read(
|
|
/* [out][in] */ BYTE __RPC_FAR *pByte,
|
|
/* [in] */ LONG cb,
|
|
/* [defaultvalue][out][in] */ LONG __RPC_FAR *pcbRead)
|
|
{
|
|
HRESULT hReturn = S_OK;
|
|
|
|
try
|
|
{
|
|
hReturn = Stream()->Read(pByte, cb, (LPDWORD)pcbRead);
|
|
}
|
|
|
|
catch (HRESULT hError)
|
|
{
|
|
hReturn = hError;
|
|
}
|
|
catch (...)
|
|
{
|
|
hReturn = E_INVALIDARG;
|
|
}
|
|
|
|
return hReturn;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Revert:
|
|
|
|
The Revert method discards all changes that have been made to a transacted
|
|
stream since the last IByteBuffer::Commit call.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
The return value is an HRESULT. A value of S_OK indicates the call was
|
|
successful and the stream was reverted to its previous version.
|
|
|
|
Remarks:
|
|
|
|
This method discards changes made to a transacted stream since the last
|
|
commit operation.
|
|
|
|
Author:
|
|
|
|
Doug Barlow (dbarlow) 6/16/1999
|
|
|
|
--*/
|
|
#undef __SUBROUTINE__
|
|
#define __SUBROUTINE__ TEXT("CByteBuffer::Revert")
|
|
|
|
STDMETHODIMP
|
|
CByteBuffer::Revert(
|
|
void)
|
|
{
|
|
HRESULT hReturn = S_OK;
|
|
|
|
try
|
|
{
|
|
hReturn = Stream()->Revert();
|
|
}
|
|
|
|
catch (HRESULT hError)
|
|
{
|
|
hReturn = hError;
|
|
}
|
|
catch (...)
|
|
{
|
|
hReturn = E_INVALIDARG;
|
|
}
|
|
|
|
return hReturn;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Seek:
|
|
|
|
The Seek method changes the seek pointer to a new location relative to the
|
|
beginning of the buffer, to the end of the buffer, or to the current seek
|
|
pointer.
|
|
|
|
Arguments:
|
|
|
|
dLibMove [in] Displacement to be added to the location indicated by
|
|
dwOrigin. If dwOrigin is STREAM_SEEK_SET, this is interpreted as an
|
|
unsigned value rather than signed.
|
|
|
|
dwOrigin [in] Specifies the origin for the displacement specified in
|
|
dlibMove. The origin can be the beginning of the file, the current
|
|
seek pointer, or the end of the file. See the STREAM_SEEK enumeration
|
|
for the values.
|
|
|
|
pLibnewPosition [out] Pointer to the location where this method writes the
|
|
value of the new seek pointer from the beginning of the stream. You
|
|
can set this pointer to NULL to indicate that you are not interested in
|
|
this value. In this case, this method does not provide the new seek
|
|
pointer.
|
|
|
|
Return Value:
|
|
|
|
The return value is an HRESULT. A value of S_OK indicates the call was
|
|
successful.
|
|
|
|
Remarks:
|
|
|
|
IByteBuffer::Seek changes the seek pointer so subsequent reads and writes
|
|
can take place at a different location in the stream object. It is an
|
|
error to seek before the beginning of the stream. It is not, however, an
|
|
error to seek past the end of the stream. Seeking past the end of the
|
|
stream is useful for subsequent writes, as the stream will at that time be
|
|
extended to the seek position immediately before the write is done.
|
|
|
|
You can also use this method to obtain the current value of the seek
|
|
pointer by calling this method with the dwOrigin parameter set to
|
|
STREAM_SEEK_CUR and the dlibMove parameter set to 0 so the seek pointer is
|
|
not changed. The current seek pointer is returned in the plibNewPosition
|
|
parameter.
|
|
|
|
Author:
|
|
|
|
Doug Barlow (dbarlow) 6/16/1999
|
|
|
|
--*/
|
|
#undef __SUBROUTINE__
|
|
#define __SUBROUTINE__ TEXT("CByteBuffer::Seek")
|
|
|
|
STDMETHODIMP
|
|
CByteBuffer::Seek(
|
|
/* [in] */ LONG dLibMove,
|
|
/* [in] */ LONG dwOrigin,
|
|
/* [defaultvalue][out][in] */ LONG __RPC_FAR *pLibnewPosition)
|
|
{
|
|
HRESULT hReturn = S_OK;
|
|
|
|
try
|
|
{
|
|
LARGE_INTEGER xlMove;
|
|
ULARGE_INTEGER xulNewPos;
|
|
|
|
SetXL(xlMove, dLibMove, 0);
|
|
SetXL(xulNewPos, 0, 0);
|
|
hReturn = Stream()->Seek(xlMove, dwOrigin, &xulNewPos);
|
|
if (NULL != pLibnewPosition)
|
|
*pLibnewPosition = xulNewPos.LowPart;
|
|
}
|
|
|
|
catch (HRESULT hError)
|
|
{
|
|
hReturn = hError;
|
|
}
|
|
catch (...)
|
|
{
|
|
hReturn = E_INVALIDARG;
|
|
}
|
|
|
|
return hReturn;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
SetSize:
|
|
|
|
The SetSize method changes the size of the stream object.
|
|
|
|
Arguments:
|
|
|
|
libNewSize [in] Specifies the new size of the stream as a number of bytes
|
|
|
|
Return Value:
|
|
|
|
The return value is an HRESULT. A value of S_OK indicates the call was
|
|
successful.
|
|
|
|
Remarks:
|
|
|
|
IByteBuffer::SetSize changes the size of the stream object. Call this
|
|
method to preallocate space for the stream. If the libNewSize parameter is
|
|
larger than the current stream size, the stream is extended to the
|
|
indicated size by filling the intervening space with bytes of undefined
|
|
value. This operation is similar to the IByteBuffer::Write method if the
|
|
seek pointer is past the current end-of-stream.
|
|
|
|
If the libNewSize parameter is smaller than the current stream, then the
|
|
stream is truncated to the indicated size.
|
|
|
|
The seek pointer is not affected by the change in stream size.
|
|
|
|
Calling IByteBuffer::SetSize can be an effective way of trying to obtain a
|
|
large chunk of contiguous space.
|
|
|
|
Author:
|
|
|
|
Doug Barlow (dbarlow) 6/16/1999
|
|
|
|
--*/
|
|
#undef __SUBROUTINE__
|
|
#define __SUBROUTINE__ TEXT("CByteBuffer::SetSize")
|
|
|
|
STDMETHODIMP
|
|
CByteBuffer::SetSize(
|
|
/* [in] */ LONG libNewSize)
|
|
{
|
|
HRESULT hReturn = S_OK;
|
|
|
|
try
|
|
{
|
|
ULARGE_INTEGER xul;
|
|
|
|
SetXL(xul, libNewSize, 0);
|
|
hReturn = Stream()->SetSize(xul);
|
|
}
|
|
|
|
catch (HRESULT hError)
|
|
{
|
|
hReturn = hError;
|
|
}
|
|
catch (...)
|
|
{
|
|
hReturn = E_INVALIDARG;
|
|
}
|
|
|
|
return hReturn;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Stat:
|
|
|
|
The Stat method retrieves statistical information from the stream object.
|
|
|
|
Arguments:
|
|
|
|
pstatstg [out] Points to a STATSTG structure where this method places
|
|
information about this stream object. This data in this structure
|
|
is meaningless if an error occurs.
|
|
|
|
grfStatFlag [in] Ignored.
|
|
|
|
Return Value:
|
|
|
|
The return value is an HRESULT. A value of S_OK indicates the call was
|
|
successful.
|
|
|
|
Remarks:
|
|
|
|
IByteBuffer::Stat retrieves a pointer to the STATSTG structure that
|
|
contains information about this open stream.
|
|
|
|
Author:
|
|
|
|
Doug Barlow (dbarlow) 6/16/1999
|
|
|
|
--*/
|
|
#undef __SUBROUTINE__
|
|
#define __SUBROUTINE__ TEXT("CByteBuffer::Stat")
|
|
|
|
STDMETHODIMP
|
|
CByteBuffer::Stat(
|
|
/* [out][in] */ LPSTATSTRUCT pstatstg,
|
|
/* [in] */ LONG grfStatFlag)
|
|
{
|
|
HRESULT hReturn = S_OK;
|
|
|
|
try
|
|
{
|
|
HRESULT hr;
|
|
STATSTG stg;
|
|
|
|
hr = Stream()->Stat(&stg, STATFLAG_NONAME);
|
|
if (FAILED(hr))
|
|
throw hr;
|
|
pstatstg->type = stg.type;
|
|
pstatstg->cbSize = stg.cbSize.LowPart;
|
|
pstatstg->grfMode = stg.grfMode;
|
|
pstatstg->grfLocksSupported = stg.grfLocksSupported;
|
|
pstatstg->grfStateBits = stg.grfStateBits;
|
|
}
|
|
|
|
catch (HRESULT hError)
|
|
{
|
|
hReturn = hError;
|
|
}
|
|
catch (...)
|
|
{
|
|
hReturn = E_INVALIDARG;
|
|
}
|
|
|
|
return hReturn;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
UnlockRegion:
|
|
|
|
The UnlockRegion method removes the access restriction on a range of bytes
|
|
previously restricted with IByteBuffer::LockRegion.
|
|
|
|
Arguments:
|
|
|
|
libOffset [in] Specifies the byte offset for the beginning of the range.
|
|
|
|
cb [in] Specifies, in bytes, the length of the range to be restricted.
|
|
|
|
dwLockType [in] Specifies the access restrictions previously placed on the
|
|
range.
|
|
|
|
Return Value:
|
|
|
|
The return value is an HRESULT. A value of S_OK indicates the call was
|
|
successful.
|
|
|
|
Remarks:
|
|
|
|
IByteBuffer::UnlockRegion unlocks a region previously locked with the
|
|
IByteBuffer::LockRegion method. Locked regions must later be explicitly
|
|
unlocked by calling IByteBuffer::UnlockRegion with exactly the same values
|
|
for the libOffset, cb, and dwLockType parameters. The region must be
|
|
unlocked before the stream is released. Two adjacent regions cannot be
|
|
locked separately and then unlocked with a single unlock call.
|
|
|
|
Author:
|
|
|
|
Doug Barlow (dbarlow) 6/16/1999
|
|
|
|
--*/
|
|
#undef __SUBROUTINE__
|
|
#define __SUBROUTINE__ TEXT("CByteBuffer::UnlockRegion")
|
|
|
|
STDMETHODIMP
|
|
CByteBuffer::UnlockRegion(
|
|
/* [in] */ LONG libOffset,
|
|
/* [in] */ LONG cb,
|
|
/* [in] */ LONG dwLockType)
|
|
{
|
|
HRESULT hReturn = S_OK;
|
|
|
|
try
|
|
{
|
|
ULARGE_INTEGER xulOffset, xulcb;
|
|
|
|
SetXL(xulOffset, libOffset, 0);
|
|
SetXL(xulcb, cb, 0);
|
|
hReturn = Stream()->UnlockRegion(xulOffset, xulcb, dwLockType);
|
|
}
|
|
|
|
catch (HRESULT hError)
|
|
{
|
|
hReturn = hError;
|
|
}
|
|
catch (...)
|
|
{
|
|
hReturn = E_INVALIDARG;
|
|
}
|
|
|
|
return hReturn;
|
|
}
|
|
|
|
|
|
/*++
|
|
|
|
Write:
|
|
|
|
The Write method writes a specified number from bytes into the stream
|
|
object starting at the current seek pointer.
|
|
|
|
Arguments:
|
|
|
|
pByte [in] Address of the buffer containing the data that is to be written
|
|
to the stream. A valid pointer must be provided for this parameter
|
|
even when cb is zero.
|
|
|
|
cb [in] The number of bytes of data to attempt to write into the stream.
|
|
Can be zero.
|
|
|
|
pcbWritten [out] Address of a LONG variable where this method writes the
|
|
actual number of bytes written to the stream object. The caller can
|
|
set this pointer to NULL, in which case, this method does not provide
|
|
the actual number of bytes written.
|
|
|
|
Return Value:
|
|
|
|
The return value is an HRESULT. A value of S_OK indicates the call was
|
|
successful.
|
|
|
|
Remarks:
|
|
|
|
IByteBuffer::Write writes the specified data to a stream object. The seek
|
|
pointer is adjusted for the number of bytes actually written. The number
|
|
of bytes actually written is returned in the pcbWritten parameter. If the
|
|
byte count is zero bytes, the write operation has no effect.
|
|
|
|
If the seek pointer is currently past the end of the stream and the byte
|
|
count is nonzero, this method increases the size of the stream to the seek
|
|
pointer and writes the specified bytes starting at the seek pointer. The
|
|
fill bytes written to the stream are not initialized to any particular
|
|
value. This is the same as the end-of-file behavior in the MS-DOS FAT file
|
|
system.
|
|
|
|
With a zero byte count and a seek pointer past the end of the stream, this
|
|
method does not create the fill bytes to increase the stream to the seek
|
|
pointer. In this case, you must call the IByteBuffer::SetSize method to
|
|
increase the size of the stream and write the fill bytes.
|
|
|
|
The pcbWritten parameter can have a value even if an error occurs.
|
|
|
|
In the COM-provided implementation, stream objects are not sparse. Any
|
|
fill bytes are eventually allocated on the disk and assigned to the stream.
|
|
|
|
Author:
|
|
|
|
Doug Barlow (dbarlow) 6/16/1999
|
|
|
|
--*/
|
|
#undef __SUBROUTINE__
|
|
#define __SUBROUTINE__ TEXT("CByteBuffer::Write")
|
|
|
|
STDMETHODIMP
|
|
CByteBuffer::Write(
|
|
/* [out][in] */ BYTE __RPC_FAR *pByte,
|
|
/* [in] */ LONG cb,
|
|
/* [out][in] */ LONG __RPC_FAR *pcbWritten)
|
|
{
|
|
HRESULT hReturn = S_OK;
|
|
|
|
try
|
|
{
|
|
hReturn = Stream()->Write(pByte, cb, (LPDWORD)pcbWritten);
|
|
}
|
|
|
|
catch (HRESULT hError)
|
|
{
|
|
hReturn = hError;
|
|
}
|
|
catch (...)
|
|
{
|
|
hReturn = E_INVALIDARG;
|
|
}
|
|
|
|
return hReturn;
|
|
}
|
|
|