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
;
208 SIZE_T LocalBytesRead
= 0;
216 CopyLength
= min(Available
, Length
);
218 Status
= NtReadVirtualMemory(Stream
->ProcessHandle
,
224 if (NT_SUCCESS(Status
))
226 Stream
->Current
= (PUCHAR
)Stream
->Current
+ LocalBytesRead
;
228 *BytesRead
= (ULONG
)LocalBytesRead
;
231 return HRESULT_FROM_WIN32(RtlNtStatusToDosError(Status
));
241 _In_ LARGE_INTEGER RelativeOffset
,
243 _Out_opt_ PULARGE_INTEGER ResultOffset
)
246 PRTL_MEMORY_STREAM Stream
= IStream_To_RTL_MEMORY_STREAM(This
);
250 case STREAM_SEEK_SET
:
251 NewPosition
= (PUCHAR
)Stream
->Start
+ RelativeOffset
.QuadPart
;
254 case STREAM_SEEK_CUR
:
255 NewPosition
= (PUCHAR
)Stream
->Current
+ RelativeOffset
.QuadPart
;
258 case STREAM_SEEK_END
:
259 NewPosition
= (PUCHAR
)Stream
->End
- RelativeOffset
.QuadPart
;
266 if (NewPosition
< Stream
->Start
|| NewPosition
> Stream
->End
)
267 return STG_E_INVALIDPOINTER
;
269 Stream
->Current
= NewPosition
;
272 ResultOffset
->QuadPart
= (PUCHAR
)Stream
->Current
- (PUCHAR
)Stream
->Start
;
282 RtlCopyMemoryStreamTo(
284 _In_ IStream
*Target
,
285 _In_ ULARGE_INTEGER Length
,
286 _Out_opt_ PULARGE_INTEGER BytesRead
,
287 _Out_opt_ PULARGE_INTEGER BytesWritten
)
295 BytesRead
->QuadPart
= 0;
297 BytesWritten
->QuadPart
= 0;
302 if (!Length
.QuadPart
)
306 TotalSize
= Length
.QuadPart
;
309 Left
= (ULONG
)min(TotalSize
, sizeof(Buffer
));
312 Result
= IStream_Read(This
, Buffer
, Left
, &Amount
);
314 BytesRead
->QuadPart
+= Amount
;
315 if (FAILED(Result
) || Amount
== 0)
321 Result
= IStream_Write(Target
, Buffer
, Left
, &Amount
);
323 BytesWritten
->QuadPart
+= Amount
;
324 if (FAILED(Result
) || Amount
!= Left
)
339 _Out_ STATSTG
*Stats
,
342 PRTL_MEMORY_STREAM Stream
= IStream_To_RTL_MEMORY_STREAM(This
);
345 return STG_E_INVALIDPOINTER
;
347 RtlZeroMemory(Stats
, sizeof(STATSTG
));
348 Stats
->type
= STGTY_STREAM
;
349 Stats
->cbSize
.QuadPart
= (PUCHAR
)Stream
->End
- (PUCHAR
)Stream
->Start
;
354 /* DUMMY FUNCTIONS ************************************************************/
356 * The following functions return E_NOTIMPL in Windows Server 2003.
364 RtlWriteMemoryStream(
366 _In_reads_bytes_(Length
) CONST VOID
*Buffer
,
368 _Out_opt_ PULONG BytesWritten
)
370 UNREFERENCED_PARAMETER(This
);
371 UNREFERENCED_PARAMETER(Buffer
);
372 UNREFERENCED_PARAMETER(Length
);
373 UNREFERENCED_PARAMETER(BytesWritten
);
383 RtlSetMemoryStreamSize(
385 _In_ ULARGE_INTEGER NewSize
)
387 UNREFERENCED_PARAMETER(This
);
388 UNREFERENCED_PARAMETER(NewSize
);
398 RtlCommitMemoryStream(
400 _In_ ULONG CommitFlags
)
402 UNREFERENCED_PARAMETER(This
);
403 UNREFERENCED_PARAMETER(CommitFlags
);
413 RtlRevertMemoryStream(
416 UNREFERENCED_PARAMETER(This
);
426 RtlLockMemoryStreamRegion(
428 _In_ ULARGE_INTEGER Offset
,
429 _In_ ULARGE_INTEGER Length
,
432 UNREFERENCED_PARAMETER(This
);
433 UNREFERENCED_PARAMETER(Offset
);
434 UNREFERENCED_PARAMETER(Length
);
435 UNREFERENCED_PARAMETER(LockType
);
445 RtlUnlockMemoryStreamRegion(
447 _In_ ULARGE_INTEGER Offset
,
448 _In_ ULARGE_INTEGER Length
,
451 UNREFERENCED_PARAMETER(This
);
452 UNREFERENCED_PARAMETER(Offset
);
453 UNREFERENCED_PARAMETER(Length
);
454 UNREFERENCED_PARAMETER(LockType
);
464 RtlCloneMemoryStream(
466 _Outptr_ IStream
**ResultStream
)
468 UNREFERENCED_PARAMETER(This
);
469 UNREFERENCED_PARAMETER(ResultStream
);
480 _Out_writes_bytes_all_(Size
) PVOID Destination
,
481 _In_reads_bytes_(Size
) const VOID
*Source
,
484 NTSTATUS Status
= STATUS_SUCCESS
;
487 RtlCopyMemory(Destination
, Source
, Size
);
489 _SEH2_EXCEPT(_SEH2_GetExceptionCode() == STATUS_IN_PAGE_ERROR
490 ? EXCEPTION_EXECUTE_HANDLER
491 : EXCEPTION_CONTINUE_SEARCH
)
493 Status
= _SEH2_GetExceptionCode();