Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries * FILE: lib/rtl/memstream.c * PURPOSE: MemoryStream functions * PROGRAMMER: David Quintana (gigaherz@gmail.com) */
/* INCLUDES *******************************************************************/
#include <rtl.h>
#define NDEBUG#include <debug.h>
/* VIRTUAL METHOD TABLES ******************************************************/
const struct IStreamVtbl RtlMemoryStreamVtbl ={ RtlQueryInterfaceMemoryStream, RtlAddRefMemoryStream, RtlReleaseMemoryStream, RtlReadMemoryStream, RtlWriteMemoryStream, RtlSeekMemoryStream, RtlSetMemoryStreamSize, RtlCopyMemoryStreamTo, RtlCommitMemoryStream, RtlRevertMemoryStream, RtlLockMemoryStreamRegion, RtlUnlockMemoryStreamRegion, RtlStatMemoryStream, RtlCloneMemoryStream,};
const struct IStreamVtbl RtlOutOfProcessMemoryStreamVtbl ={ RtlQueryInterfaceMemoryStream, RtlAddRefMemoryStream, RtlReleaseMemoryStream, RtlReadOutOfProcessMemoryStream, RtlWriteMemoryStream, RtlSeekMemoryStream, RtlSetMemoryStreamSize, RtlCopyMemoryStreamTo, RtlCommitMemoryStream, RtlRevertMemoryStream, RtlLockMemoryStreamRegion, RtlUnlockMemoryStreamRegion, RtlStatMemoryStream, RtlCloneMemoryStream,};
/* FUNCTIONS ******************************************************************/
staticPRTL_MEMORY_STREAMIStream_To_RTL_MEMORY_STREAM( _In_ IStream *Interface){ if (Interface == NULL) return NULL;
return CONTAINING_RECORD(Interface, RTL_MEMORY_STREAM, Vtbl);}
/* * @implemented */VOIDNTAPIRtlInitMemoryStream( _Out_ PRTL_MEMORY_STREAM Stream){ RtlZeroMemory(Stream, sizeof(RTL_MEMORY_STREAM)); Stream->Vtbl = &RtlMemoryStreamVtbl;}
/* * @implemented */VOIDNTAPIRtlInitOutOfProcessMemoryStream( _Out_ PRTL_MEMORY_STREAM Stream){ RtlZeroMemory(Stream, sizeof(RTL_MEMORY_STREAM)); Stream->Vtbl = &RtlOutOfProcessMemoryStreamVtbl; Stream->FinalRelease = RtlFinalReleaseOutOfProcessMemoryStream;}
/* * @unimplemented */VOIDNTAPIRtlFinalReleaseOutOfProcessMemoryStream( _In_ PRTL_MEMORY_STREAM Stream){ UNIMPLEMENTED;}
/* * @implemented */HRESULTNTAPIRtlQueryInterfaceMemoryStream( _In_ IStream *This, _In_ REFIID RequestedIid, _Outptr_ PVOID *ResultObject){ if (IsEqualGUID(RequestedIid, &IID_IUnknown) || IsEqualGUID(RequestedIid, &IID_ISequentialStream) || IsEqualGUID(RequestedIid, &IID_IStream)) { IStream_AddRef(This); *ResultObject = This; return S_OK; }
*ResultObject = NULL; return E_NOINTERFACE;}
/* * @implemented */ULONGNTAPIRtlAddRefMemoryStream( _In_ IStream *This){ PRTL_MEMORY_STREAM Stream = IStream_To_RTL_MEMORY_STREAM(This);
return InterlockedIncrement(&Stream->RefCount);}
/* * @implemented */ULONGNTAPIRtlReleaseMemoryStream( _In_ IStream *This){ PRTL_MEMORY_STREAM Stream = IStream_To_RTL_MEMORY_STREAM(This); LONG Result;
Result = InterlockedDecrement(&Stream->RefCount);
if (Result == 0) { if (Stream->FinalRelease) Stream->FinalRelease(Stream); }
return Result;}
/* * @implemented */HRESULTNTAPIRtlReadMemoryStream( _In_ IStream *This, _Out_writes_bytes_(Length) PVOID Buffer, _In_ ULONG Length, _Out_opt_ PULONG BytesRead){ ULONG CopyLength; PRTL_MEMORY_STREAM Stream = IStream_To_RTL_MEMORY_STREAM(This); SIZE_T Available = (PUCHAR)Stream->End - (PUCHAR)Stream->Current;
if (BytesRead) *BytesRead = 0;
if (!Length) return S_OK;
CopyLength = min(Available, Length);
RtlMoveMemory(Buffer, Stream->Current, CopyLength);
Stream->Current = (PUCHAR)Stream->Current + CopyLength;
*BytesRead = CopyLength;
return S_OK;}
/* * @implemented */HRESULTNTAPIRtlReadOutOfProcessMemoryStream( _In_ IStream *This, _Out_writes_bytes_(Length) PVOID Buffer, _In_ ULONG Length, _Out_opt_ PULONG BytesRead){ NTSTATUS Status; ULONG CopyLength; PRTL_MEMORY_STREAM Stream = IStream_To_RTL_MEMORY_STREAM(This); SIZE_T Available = (PUCHAR)Stream->End - (PUCHAR)Stream->Current; SIZE_T LocalBytesRead = 0;
if (BytesRead) *BytesRead = 0;
if (!Length) return S_OK;
CopyLength = min(Available, Length);
Status = NtReadVirtualMemory(Stream->ProcessHandle, Stream->Current, Buffer, CopyLength, &LocalBytesRead);
if (NT_SUCCESS(Status)) { Stream->Current = (PUCHAR)Stream->Current + LocalBytesRead; if (BytesRead) *BytesRead = (ULONG)LocalBytesRead; }
return HRESULT_FROM_WIN32(RtlNtStatusToDosError(Status));}
/* * @implemented */HRESULTNTAPIRtlSeekMemoryStream( _In_ IStream *This, _In_ LARGE_INTEGER RelativeOffset, _In_ ULONG Origin, _Out_opt_ PULARGE_INTEGER ResultOffset){ PVOID NewPosition; PRTL_MEMORY_STREAM Stream = IStream_To_RTL_MEMORY_STREAM(This);
switch (Origin) { case STREAM_SEEK_SET: NewPosition = (PUCHAR)Stream->Start + RelativeOffset.QuadPart; break;
case STREAM_SEEK_CUR: NewPosition = (PUCHAR)Stream->Current + RelativeOffset.QuadPart; break;
case STREAM_SEEK_END: NewPosition = (PUCHAR)Stream->End - RelativeOffset.QuadPart; break;
default: return E_INVALIDARG; }
if (NewPosition < Stream->Start || NewPosition > Stream->End) return STG_E_INVALIDPOINTER;
Stream->Current = NewPosition;
if (ResultOffset) ResultOffset->QuadPart = (PUCHAR)Stream->Current - (PUCHAR)Stream->Start;
return S_OK;}
/* * @implemented */HRESULTNTAPIRtlCopyMemoryStreamTo( _In_ IStream *This, _In_ IStream *Target, _In_ ULARGE_INTEGER Length, _Out_opt_ PULARGE_INTEGER BytesRead, _Out_opt_ PULARGE_INTEGER BytesWritten){ CHAR Buffer[1024]; ULONGLONG TotalSize; ULONG Left, Amount; HRESULT Result;
if (BytesRead) BytesRead->QuadPart = 0; if (BytesWritten) BytesWritten->QuadPart = 0;
if (!Target) return S_OK;
if (!Length.QuadPart) return S_OK;
/* Copy data */ TotalSize = Length.QuadPart; while (TotalSize) { Left = (ULONG)min(TotalSize, sizeof(Buffer));
/* Read */ Result = IStream_Read(This, Buffer, Left, &Amount); if (BytesRead) BytesRead->QuadPart += Amount; if (FAILED(Result) || Amount == 0) break;
Left = Amount;
/* Write */ Result = IStream_Write(Target, Buffer, Left, &Amount); if (BytesWritten) BytesWritten->QuadPart += Amount; if (FAILED(Result) || Amount != Left) break;
TotalSize -= Left; } return Result;}
/* * @implemented */HRESULTNTAPIRtlStatMemoryStream( _In_ IStream *This, _Out_ STATSTG *Stats, _In_ ULONG Flags){ PRTL_MEMORY_STREAM Stream = IStream_To_RTL_MEMORY_STREAM(This);
if (!Stats) return STG_E_INVALIDPOINTER;
RtlZeroMemory(Stats, sizeof(STATSTG)); Stats->type = STGTY_STREAM; Stats->cbSize.QuadPart = (PUCHAR)Stream->End - (PUCHAR)Stream->Start;
return S_OK;}
/* DUMMY FUNCTIONS ************************************************************//* * The following functions return E_NOTIMPL in Windows Server 2003. */
/* * @implemented */HRESULTNTAPIRtlWriteMemoryStream( _In_ IStream *This, _In_reads_bytes_(Length) CONST VOID *Buffer, _In_ ULONG Length, _Out_opt_ PULONG BytesWritten){ UNREFERENCED_PARAMETER(This); UNREFERENCED_PARAMETER(Buffer); UNREFERENCED_PARAMETER(Length); UNREFERENCED_PARAMETER(BytesWritten);
return E_NOTIMPL;}
/* * @implemented */HRESULTNTAPIRtlSetMemoryStreamSize( _In_ IStream *This, _In_ ULARGE_INTEGER NewSize){ UNREFERENCED_PARAMETER(This); UNREFERENCED_PARAMETER(NewSize);
return E_NOTIMPL;}
/* * @implemented */HRESULTNTAPIRtlCommitMemoryStream( _In_ IStream *This, _In_ ULONG CommitFlags){ UNREFERENCED_PARAMETER(This); UNREFERENCED_PARAMETER(CommitFlags);
return E_NOTIMPL;}
/* * @implemented */HRESULTNTAPIRtlRevertMemoryStream( _In_ IStream *This){ UNREFERENCED_PARAMETER(This);
return E_NOTIMPL;}
/* * @implemented */HRESULTNTAPIRtlLockMemoryStreamRegion( _In_ IStream *This, _In_ ULARGE_INTEGER Offset, _In_ ULARGE_INTEGER Length, _In_ ULONG LockType){ UNREFERENCED_PARAMETER(This); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Length); UNREFERENCED_PARAMETER(LockType);
return E_NOTIMPL;}
/* * @implemented */HRESULTNTAPIRtlUnlockMemoryStreamRegion( _In_ IStream *This, _In_ ULARGE_INTEGER Offset, _In_ ULARGE_INTEGER Length, _In_ ULONG LockType){ UNREFERENCED_PARAMETER(This); UNREFERENCED_PARAMETER(Offset); UNREFERENCED_PARAMETER(Length); UNREFERENCED_PARAMETER(LockType);
return E_NOTIMPL;}
/* * @implemented */HRESULTNTAPIRtlCloneMemoryStream( _In_ IStream *This, _Outptr_ IStream **ResultStream){ UNREFERENCED_PARAMETER(This); UNREFERENCED_PARAMETER(ResultStream);
return E_NOTIMPL;}
/* * @implemented */NTSTATUSNTAPIRtlCopyMappedMemory( _Out_writes_bytes_all_(Size) PVOID Destination, _In_reads_bytes_(Size) const VOID *Source, _In_ SIZE_T Size){ NTSTATUS Status = STATUS_SUCCESS; _SEH2_TRY { RtlCopyMemory(Destination, Source, Size); } _SEH2_EXCEPT(_SEH2_GetExceptionCode() == STATUS_IN_PAGE_ERROR ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) { Status = _SEH2_GetExceptionCode(); } _SEH2_END; return Status;}