2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/rtl/memstream.c
5 * PURPOSE: MemoryStream functions
6 * PROGRAMMER: David Quintana (gigaherz@gmail.com)
9 /* INCLUDES *******************************************************************/
16 /* VIRTUAL METHOD TABLES ******************************************************/
18 const struct IStreamVtbl RtlMemoryStreamVtbl
=
20 RtlQueryInterfaceMemoryStream
,
21 RtlAddRefMemoryStream
,
22 RtlReleaseMemoryStream
,
26 RtlSetMemoryStreamSize
,
27 RtlCopyMemoryStreamTo
,
28 RtlCommitMemoryStream
,
29 RtlRevertMemoryStream
,
30 RtlLockMemoryStreamRegion
,
31 RtlUnlockMemoryStreamRegion
,
36 const struct IStreamVtbl RtlOutOfProcessMemoryStreamVtbl
=
38 RtlQueryInterfaceMemoryStream
,
39 RtlAddRefMemoryStream
,
40 RtlReleaseMemoryStream
,
41 RtlReadOutOfProcessMemoryStream
,
44 RtlSetMemoryStreamSize
,
45 RtlCopyMemoryStreamTo
,
46 RtlCommitMemoryStream
,
47 RtlRevertMemoryStream
,
48 RtlLockMemoryStreamRegion
,
49 RtlUnlockMemoryStreamRegion
,
54 /* FUNCTIONS ******************************************************************/
58 IStream_To_RTL_MEMORY_STREAM(
59 _In_ IStream
*Interface
)
61 if (Interface
== NULL
)
64 return CONTAINING_RECORD(Interface
, RTL_MEMORY_STREAM
, Vtbl
);
73 _Out_ PRTL_MEMORY_STREAM Stream
)
75 RtlZeroMemory(Stream
, sizeof(RTL_MEMORY_STREAM
));
76 Stream
->Vtbl
= &RtlMemoryStreamVtbl
;
84 RtlInitOutOfProcessMemoryStream(
85 _Out_ PRTL_MEMORY_STREAM Stream
)
87 RtlZeroMemory(Stream
, sizeof(RTL_MEMORY_STREAM
));
88 Stream
->Vtbl
= &RtlOutOfProcessMemoryStreamVtbl
;
89 Stream
->FinalRelease
= RtlFinalReleaseOutOfProcessMemoryStream
;
97 RtlFinalReleaseOutOfProcessMemoryStream(
98 _In_ PRTL_MEMORY_STREAM Stream
)
108 RtlQueryInterfaceMemoryStream(
110 _In_ REFIID RequestedIid
,
111 _Outptr_ PVOID
*ResultObject
)
113 if (IsEqualGUID(RequestedIid
, &IID_IUnknown
) ||
114 IsEqualGUID(RequestedIid
, &IID_ISequentialStream
) ||
115 IsEqualGUID(RequestedIid
, &IID_IStream
))
117 IStream_AddRef(This
);
118 *ResultObject
= This
;
122 *ResultObject
= NULL
;
123 return E_NOINTERFACE
;
131 RtlAddRefMemoryStream(
134 PRTL_MEMORY_STREAM Stream
= IStream_To_RTL_MEMORY_STREAM(This
);
136 return InterlockedIncrement(&Stream
->RefCount
);
144 RtlReleaseMemoryStream(
147 PRTL_MEMORY_STREAM Stream
= IStream_To_RTL_MEMORY_STREAM(This
);
150 Result
= InterlockedDecrement(&Stream
->RefCount
);
154 if (Stream
->FinalRelease
)
155 Stream
->FinalRelease(Stream
);
168 _Out_writes_bytes_(Length
) PVOID Buffer
,
170 _Out_opt_ PULONG BytesRead
)
173 PRTL_MEMORY_STREAM Stream
= IStream_To_RTL_MEMORY_STREAM(This
);
174 SIZE_T Available
= (PUCHAR
)Stream
->End
- (PUCHAR
)Stream
->Current
;
182 CopyLength
= min(Available
, Length
);
184 RtlMoveMemory(Buffer
, Stream
->Current
, CopyLength
);
186 Stream
->Current
= (PUCHAR
)Stream
->Current
+ CopyLength
;
188 *BytesRead
= CopyLength
;
198 RtlReadOutOfProcessMemoryStream(
200 _Out_writes_bytes_(Length
) PVOID Buffer
,
202 _Out_opt_ PULONG BytesRead
)
206 PRTL_MEMORY_STREAM Stream
= IStream_To_RTL_MEMORY_STREAM(This
);
207 SIZE_T Available
= (PUCHAR
)Stream
->End
- (PUCHAR
)Stream
->Current
;
215 CopyLength
= min(Available
, Length
);
217 Status
= NtReadVirtualMemory(Stream
->ProcessHandle
,
223 if (NT_SUCCESS(Status
))
224 Stream
->Current
= (PUCHAR
)Stream
->Current
+ *BytesRead
;
226 return HRESULT_FROM_WIN32(RtlNtStatusToDosError(Status
));
236 _In_ LARGE_INTEGER RelativeOffset
,
238 _Out_opt_ PULARGE_INTEGER ResultOffset
)
241 PRTL_MEMORY_STREAM Stream
= IStream_To_RTL_MEMORY_STREAM(This
);
245 case STREAM_SEEK_SET
:
246 NewPosition
= (PUCHAR
)Stream
->Start
+ RelativeOffset
.QuadPart
;
249 case STREAM_SEEK_CUR
:
250 NewPosition
= (PUCHAR
)Stream
->Current
+ RelativeOffset
.QuadPart
;
253 case STREAM_SEEK_END
:
254 NewPosition
= (PUCHAR
)Stream
->End
- RelativeOffset
.QuadPart
;
261 if (NewPosition
< Stream
->Start
|| NewPosition
> Stream
->End
)
262 return STG_E_INVALIDPOINTER
;
264 Stream
->Current
= NewPosition
;
267 ResultOffset
->QuadPart
= (PUCHAR
)Stream
->Current
- (PUCHAR
)Stream
->Start
;
277 RtlCopyMemoryStreamTo(
279 _In_ IStream
*Target
,
280 _In_ ULARGE_INTEGER Length
,
281 _Out_opt_ PULARGE_INTEGER BytesRead
,
282 _Out_opt_ PULARGE_INTEGER BytesWritten
)
290 BytesRead
->QuadPart
= 0;
292 BytesWritten
->QuadPart
= 0;
297 if (!Length
.QuadPart
)
301 TotalSize
= Length
.QuadPart
;
304 Left
= (ULONG
)min(TotalSize
, sizeof(Buffer
));
307 Result
= IStream_Read(This
, Buffer
, Left
, &Amount
);
309 BytesRead
->QuadPart
+= Amount
;
310 if (FAILED(Result
) || Amount
== 0)
316 Result
= IStream_Write(Target
, Buffer
, Left
, &Amount
);
318 BytesWritten
->QuadPart
+= Amount
;
319 if (FAILED(Result
) || Amount
!= Left
)
334 _Out_ STATSTG
*Stats
,
337 PRTL_MEMORY_STREAM Stream
= IStream_To_RTL_MEMORY_STREAM(This
);
340 return STG_E_INVALIDPOINTER
;
342 RtlZeroMemory(Stats
, sizeof(STATSTG
));
343 Stats
->type
= STGTY_STREAM
;
344 Stats
->cbSize
.QuadPart
= (PUCHAR
)Stream
->End
- (PUCHAR
)Stream
->Start
;
349 /* DUMMY FUNCTIONS ************************************************************/
351 * The following functions return E_NOTIMPL in Windows Server 2003.
359 RtlWriteMemoryStream(
361 _In_reads_bytes_(Length
) CONST VOID
*Buffer
,
363 _Out_opt_ PULONG BytesWritten
)
365 UNREFERENCED_PARAMETER(This
);
366 UNREFERENCED_PARAMETER(Buffer
);
367 UNREFERENCED_PARAMETER(Length
);
368 UNREFERENCED_PARAMETER(BytesWritten
);
378 RtlSetMemoryStreamSize(
380 _In_ ULARGE_INTEGER NewSize
)
382 UNREFERENCED_PARAMETER(This
);
383 UNREFERENCED_PARAMETER(NewSize
);
393 RtlCommitMemoryStream(
395 _In_ ULONG CommitFlags
)
397 UNREFERENCED_PARAMETER(This
);
398 UNREFERENCED_PARAMETER(CommitFlags
);
408 RtlRevertMemoryStream(
411 UNREFERENCED_PARAMETER(This
);
421 RtlLockMemoryStreamRegion(
423 _In_ ULARGE_INTEGER Offset
,
424 _In_ ULARGE_INTEGER Length
,
427 UNREFERENCED_PARAMETER(This
);
428 UNREFERENCED_PARAMETER(Offset
);
429 UNREFERENCED_PARAMETER(Length
);
430 UNREFERENCED_PARAMETER(LockType
);
440 RtlUnlockMemoryStreamRegion(
442 _In_ ULARGE_INTEGER Offset
,
443 _In_ ULARGE_INTEGER Length
,
446 UNREFERENCED_PARAMETER(This
);
447 UNREFERENCED_PARAMETER(Offset
);
448 UNREFERENCED_PARAMETER(Length
);
449 UNREFERENCED_PARAMETER(LockType
);
459 RtlCloneMemoryStream(
461 _Outptr_ IStream
**ResultStream
)
463 UNREFERENCED_PARAMETER(This
);
464 UNREFERENCED_PARAMETER(ResultStream
);
475 _Out_writes_bytes_all_(Size
) PVOID Destination
,
476 _In_reads_bytes_(Size
) const VOID
*Source
,
479 NTSTATUS Status
= STATUS_SUCCESS
;
482 RtlCopyMemory(Destination
, Source
, Size
);
484 _SEH2_EXCEPT(_SEH2_GetExceptionCode() == STATUS_IN_PAGE_ERROR
485 ? EXCEPTION_EXECUTE_HANDLER
486 : EXCEPTION_CONTINUE_SEARCH
)
488 Status
= _SEH2_GetExceptionCode();