ReactOS 0.4.15-dev-7942-gd23573b
memstream.c
Go to the documentation of this file.
1/*
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)
7 */
8
9/* INCLUDES *******************************************************************/
10
11#include <rtl.h>
12
13#define NDEBUG
14#include <debug.h>
15
16/* VIRTUAL METHOD TABLES ******************************************************/
17
18const struct IStreamVtbl RtlMemoryStreamVtbl =
19{
34};
35
36const struct IStreamVtbl RtlOutOfProcessMemoryStreamVtbl =
37{
52};
53
54/* FUNCTIONS ******************************************************************/
55
56static
57PRTL_MEMORY_STREAM
60{
61 if (Interface == NULL)
62 return NULL;
63
64 return CONTAINING_RECORD(Interface, RTL_MEMORY_STREAM, Vtbl);
65}
66
67/*
68 * @implemented
69 */
70VOID
73 _Out_ PRTL_MEMORY_STREAM Stream)
74{
75 RtlZeroMemory(Stream, sizeof(RTL_MEMORY_STREAM));
77}
78
79/*
80 * @implemented
81 */
82VOID
85 _Out_ PRTL_MEMORY_STREAM Stream)
86{
87 RtlZeroMemory(Stream, sizeof(RTL_MEMORY_STREAM));
90}
91
92/*
93 * @unimplemented
94 */
95VOID
98 _In_ PRTL_MEMORY_STREAM Stream)
99{
101}
102
103/*
104 * @implemented
105 */
107NTAPI
110 _In_ REFIID RequestedIid,
111 _Outptr_ PVOID *ResultObject)
112{
113 if (IsEqualGUID(RequestedIid, &IID_IUnknown) ||
114 IsEqualGUID(RequestedIid, &IID_ISequentialStream) ||
115 IsEqualGUID(RequestedIid, &IID_IStream))
116 {
117 IStream_AddRef(This);
118 *ResultObject = This;
119 return S_OK;
120 }
121
122 *ResultObject = NULL;
123 return E_NOINTERFACE;
124}
125
126/*
127 * @implemented
128 */
129ULONG
130NTAPI
133{
134 PRTL_MEMORY_STREAM Stream = IStream_To_RTL_MEMORY_STREAM(This);
135
136 return InterlockedIncrement(&Stream->RefCount);
137}
138
139/*
140 * @implemented
141 */
142ULONG
143NTAPI
146{
147 PRTL_MEMORY_STREAM Stream = IStream_To_RTL_MEMORY_STREAM(This);
148 LONG Result;
149
150 Result = InterlockedDecrement(&Stream->RefCount);
151
152 if (Result == 0)
153 {
154 if (Stream->FinalRelease)
155 Stream->FinalRelease(Stream);
156 }
157
158 return Result;
159}
160
161/*
162 * @implemented
163 */
165NTAPI
171{
172 ULONG CopyLength;
173 PRTL_MEMORY_STREAM Stream = IStream_To_RTL_MEMORY_STREAM(This);
174 SIZE_T Available = (PUCHAR)Stream->End - (PUCHAR)Stream->Current;
175
176 if (BytesRead)
177 *BytesRead = 0;
178
179 if (!Length)
180 return S_OK;
181
182 CopyLength = min(Available, Length);
183
184 RtlMoveMemory(Buffer, Stream->Current, CopyLength);
185
186 Stream->Current = (PUCHAR)Stream->Current + CopyLength;
187
188 *BytesRead = CopyLength;
189
190 return S_OK;
191}
192
193/*
194 * @implemented
195 */
197NTAPI
203{
205 ULONG CopyLength;
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;
209
210 if (BytesRead)
211 *BytesRead = 0;
212
213 if (!Length)
214 return S_OK;
215
216 CopyLength = min(Available, Length);
217
218 Status = NtReadVirtualMemory(Stream->ProcessHandle,
219 Stream->Current,
220 Buffer,
221 CopyLength,
222 &LocalBytesRead);
223
224 if (NT_SUCCESS(Status))
225 {
226 Stream->Current = (PUCHAR)Stream->Current + LocalBytesRead;
227 if (BytesRead)
228 *BytesRead = (ULONG)LocalBytesRead;
229 }
230
232}
233
234/*
235 * @implemented
236 */
238NTAPI
241 _In_ LARGE_INTEGER RelativeOffset,
242 _In_ ULONG Origin,
243 _Out_opt_ PULARGE_INTEGER ResultOffset)
244{
245 PVOID NewPosition;
246 PRTL_MEMORY_STREAM Stream = IStream_To_RTL_MEMORY_STREAM(This);
247
248 switch (Origin)
249 {
250 case STREAM_SEEK_SET:
251 NewPosition = (PUCHAR)Stream->Start + RelativeOffset.QuadPart;
252 break;
253
254 case STREAM_SEEK_CUR:
255 NewPosition = (PUCHAR)Stream->Current + RelativeOffset.QuadPart;
256 break;
257
258 case STREAM_SEEK_END:
259 NewPosition = (PUCHAR)Stream->End - RelativeOffset.QuadPart;
260 break;
261
262 default:
263 return E_INVALIDARG;
264 }
265
266 if (NewPosition < Stream->Start || NewPosition > Stream->End)
268
269 Stream->Current = NewPosition;
270
271 if (ResultOffset)
272 ResultOffset->QuadPart = (PUCHAR)Stream->Current - (PUCHAR)Stream->Start;
273
274 return S_OK;
275}
276
277/*
278 * @implemented
279 */
281NTAPI
288{
289 CHAR Buffer[1024];
290 ULONGLONG TotalSize;
291 ULONG Left, Amount;
293
294 if (BytesRead)
295 BytesRead->QuadPart = 0;
296 if (BytesWritten)
297 BytesWritten->QuadPart = 0;
298
299 if (!Target)
300 return S_OK;
301
302 if (!Length.QuadPart)
303 return S_OK;
304
305 /* Copy data */
306 TotalSize = Length.QuadPart;
307 while (TotalSize)
308 {
309 Left = (ULONG)min(TotalSize, sizeof(Buffer));
310
311 /* Read */
312 Result = IStream_Read(This, Buffer, Left, &Amount);
313 if (BytesRead)
314 BytesRead->QuadPart += Amount;
315 if (FAILED(Result) || Amount == 0)
316 break;
317
318 Left = Amount;
319
320 /* Write */
321 Result = IStream_Write(Target, Buffer, Left, &Amount);
322 if (BytesWritten)
323 BytesWritten->QuadPart += Amount;
324 if (FAILED(Result) || Amount != Left)
325 break;
326
327 TotalSize -= Left;
328 }
329 return Result;
330}
331
332/*
333 * @implemented
334 */
336NTAPI
339 _Out_ STATSTG *Stats,
341{
342 PRTL_MEMORY_STREAM Stream = IStream_To_RTL_MEMORY_STREAM(This);
343
344 if (!Stats)
346
347 RtlZeroMemory(Stats, sizeof(STATSTG));
348 Stats->type = STGTY_STREAM;
349 Stats->cbSize.QuadPart = (PUCHAR)Stream->End - (PUCHAR)Stream->Start;
350
351 return S_OK;
352}
353
354/* DUMMY FUNCTIONS ************************************************************/
355/*
356 * The following functions return E_NOTIMPL in Windows Server 2003.
357 */
358
359/*
360 * @implemented
361 */
363NTAPI
369{
374
375 return E_NOTIMPL;
376}
377
378/*
379 * @implemented
380 */
382NTAPI
386{
389
390 return E_NOTIMPL;
391}
392
393/*
394 * @implemented
395 */
397NTAPI
400 _In_ ULONG CommitFlags)
401{
403 UNREFERENCED_PARAMETER(CommitFlags);
404
405 return E_NOTIMPL;
406}
407
408/*
409 * @implemented
410 */
412NTAPI
415{
417
418 return E_NOTIMPL;
419}
420
421/*
422 * @implemented
423 */
425NTAPI
431{
436
437 return E_NOTIMPL;
438}
439
440/*
441 * @implemented
442 */
444NTAPI
450{
455
456 return E_NOTIMPL;
457}
458
459/*
460 * @implemented
461 */
463NTAPI
466 _Outptr_ IStream **ResultStream)
467{
469 UNREFERENCED_PARAMETER(ResultStream);
470
471 return E_NOTIMPL;
472}
473
474/*
475 * @implemented
476 */
478NTAPI
483{
486 {
488 }
492 {
494 }
495 _SEH2_END;
496 return Status;
497}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
LONG NTSTATUS
Definition: precomp.h:26
const GUID IID_IUnknown
#define UNIMPLEMENTED
Definition: debug.h:115
_In_ WDFREQUEST _In_ MEDIA_LOCK_TYPE LockType
Definition: cdrom.h:1335
Definition: bufpool.h:45
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
_Must_inspect_result_ _In_ LONGLONG _In_ LONGLONG Amount
Definition: fsrtlfuncs.h:551
Status
Definition: gdiplustypes.h:25
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:86
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
if(dx< 0)
Definition: linetemp.h:194
const struct IStreamVtbl RtlOutOfProcessMemoryStreamVtbl
Definition: memstream.c:36
HRESULT NTAPI RtlSeekMemoryStream(_In_ IStream *This, _In_ LARGE_INTEGER RelativeOffset, _In_ ULONG Origin, _Out_opt_ PULARGE_INTEGER ResultOffset)
Definition: memstream.c:239
VOID NTAPI RtlFinalReleaseOutOfProcessMemoryStream(_In_ PRTL_MEMORY_STREAM Stream)
Definition: memstream.c:97
VOID NTAPI RtlInitMemoryStream(_Out_ PRTL_MEMORY_STREAM Stream)
Definition: memstream.c:72
HRESULT NTAPI RtlQueryInterfaceMemoryStream(_In_ IStream *This, _In_ REFIID RequestedIid, _Outptr_ PVOID *ResultObject)
Definition: memstream.c:108
HRESULT NTAPI RtlSetMemoryStreamSize(_In_ IStream *This, _In_ ULARGE_INTEGER NewSize)
Definition: memstream.c:383
static PRTL_MEMORY_STREAM IStream_To_RTL_MEMORY_STREAM(_In_ IStream *Interface)
Definition: memstream.c:58
HRESULT NTAPI RtlCopyMemoryStreamTo(_In_ IStream *This, _In_ IStream *Target, _In_ ULARGE_INTEGER Length, _Out_opt_ PULARGE_INTEGER BytesRead, _Out_opt_ PULARGE_INTEGER BytesWritten)
Definition: memstream.c:282
HRESULT NTAPI RtlCommitMemoryStream(_In_ IStream *This, _In_ ULONG CommitFlags)
Definition: memstream.c:398
NTSTATUS NTAPI RtlCopyMappedMemory(_Out_writes_bytes_all_(Size) PVOID Destination, _In_reads_bytes_(Size) const VOID *Source, _In_ SIZE_T Size)
Definition: memstream.c:479
HRESULT NTAPI RtlReadOutOfProcessMemoryStream(_In_ IStream *This, _Out_writes_bytes_(Length) PVOID Buffer, _In_ ULONG Length, _Out_opt_ PULONG BytesRead)
Definition: memstream.c:198
ULONG NTAPI RtlAddRefMemoryStream(_In_ IStream *This)
Definition: memstream.c:131
HRESULT NTAPI RtlLockMemoryStreamRegion(_In_ IStream *This, _In_ ULARGE_INTEGER Offset, _In_ ULARGE_INTEGER Length, _In_ ULONG LockType)
Definition: memstream.c:426
VOID NTAPI RtlInitOutOfProcessMemoryStream(_Out_ PRTL_MEMORY_STREAM Stream)
Definition: memstream.c:84
HRESULT NTAPI RtlWriteMemoryStream(_In_ IStream *This, _In_reads_bytes_(Length) CONST VOID *Buffer, _In_ ULONG Length, _Out_opt_ PULONG BytesWritten)
Definition: memstream.c:364
HRESULT NTAPI RtlUnlockMemoryStreamRegion(_In_ IStream *This, _In_ ULARGE_INTEGER Offset, _In_ ULARGE_INTEGER Length, _In_ ULONG LockType)
Definition: memstream.c:445
HRESULT NTAPI RtlReadMemoryStream(_In_ IStream *This, _Out_writes_bytes_(Length) PVOID Buffer, _In_ ULONG Length, _Out_opt_ PULONG BytesRead)
Definition: memstream.c:166
const struct IStreamVtbl RtlMemoryStreamVtbl
Definition: memstream.c:18
HRESULT NTAPI RtlCloneMemoryStream(_In_ IStream *This, _Outptr_ IStream **ResultStream)
Definition: memstream.c:464
ULONG NTAPI RtlReleaseMemoryStream(_In_ IStream *This)
Definition: memstream.c:144
HRESULT NTAPI RtlRevertMemoryStream(_In_ IStream *This)
Definition: memstream.c:413
HRESULT NTAPI RtlStatMemoryStream(_In_ IStream *This, _Out_ STATSTG *Stats, _In_ ULONG Flags)
Definition: memstream.c:337
static IStream Stream
Definition: htmldoc.c:1115
#define min(a, b)
Definition: monoChain.cc:55
#define _Out_opt_
Definition: ms_sal.h:346
#define _In_reads_bytes_(size)
Definition: ms_sal.h:321
#define _Out_writes_bytes_(size)
Definition: ms_sal.h:350
#define _Out_writes_bytes_all_(size)
Definition: ms_sal.h:362
#define _Outptr_
Definition: ms_sal.h:427
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:3004
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
NTSTATUS NTAPI NtReadVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, OUT PVOID Buffer, IN SIZE_T NumberOfBytesToRead, OUT PSIZE_T NumberOfBytesRead OPTIONAL)
Definition: virtual.c:2816
#define STATUS_IN_PAGE_ERROR
Definition: ntstatus.h:243
#define CONST
Definition: pedump.c:81
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define STATUS_SUCCESS
Definition: shellext.h:65
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
@ Start
Definition: partlist.h:33
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE Interface
Definition: wdffdo.h:465
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesWritten
Definition: wdfiotarget.h:960
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesRead
Definition: wdfiotarget.h:870
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
#define STG_E_INVALIDPOINTER
Definition: winerror.h:2571
#define E_NOINTERFACE
Definition: winerror.h:2364
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
char CHAR
Definition: xmlstorage.h:175