ReactOS  0.4.13-dev-259-g5ca9c9c
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 
18 const struct IStreamVtbl RtlMemoryStreamVtbl =
19 {
34 };
35 
36 const struct IStreamVtbl RtlOutOfProcessMemoryStreamVtbl =
37 {
52 };
53 
54 /* FUNCTIONS ******************************************************************/
55 
56 static
57 PRTL_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  */
70 VOID
71 NTAPI
73  _Out_ PRTL_MEMORY_STREAM Stream)
74 {
75  RtlZeroMemory(Stream, sizeof(RTL_MEMORY_STREAM));
76  Stream->Vtbl = &RtlMemoryStreamVtbl;
77 }
78 
79 /*
80  * @implemented
81  */
82 VOID
83 NTAPI
85  _Out_ PRTL_MEMORY_STREAM Stream)
86 {
87  RtlZeroMemory(Stream, sizeof(RTL_MEMORY_STREAM));
90 }
91 
92 /*
93  * @unimplemented
94  */
95 VOID
96 NTAPI
98  _In_ PRTL_MEMORY_STREAM Stream)
99 {
101 }
102 
103 /*
104  * @implemented
105  */
106 HRESULT
107 NTAPI
109  _In_ IStream *This,
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  */
129 ULONG
130 NTAPI
132  _In_ IStream *This)
133 {
134  PRTL_MEMORY_STREAM Stream = IStream_To_RTL_MEMORY_STREAM(This);
135 
136  return InterlockedIncrement(&Stream->RefCount);
137 }
138 
139 /*
140  * @implemented
141  */
142 ULONG
143 NTAPI
145  _In_ IStream *This)
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  */
164 HRESULT
165 NTAPI
167  _In_ IStream *This,
169  _In_ ULONG Length,
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  */
196 HRESULT
197 NTAPI
199  _In_ IStream *This,
201  _In_ ULONG Length,
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  */
237 HRESULT
238 NTAPI
240  _In_ IStream *This,
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)
267  return STG_E_INVALIDPOINTER;
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  */
280 HRESULT
281 NTAPI
283  _In_ IStream *This,
288 {
289  CHAR Buffer[1024];
290  ULONGLONG TotalSize;
291  ULONG Left, Amount;
292  HRESULT Result;
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)
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)
324  if (FAILED(Result) || Amount != Left)
325  break;
326 
327  TotalSize -= Left;
328  }
329  return Result;
330 }
331 
332 /*
333  * @implemented
334  */
335 HRESULT
336 NTAPI
338  _In_ IStream *This,
339  _Out_ STATSTG *Stats,
340  _In_ ULONG Flags)
341 {
342  PRTL_MEMORY_STREAM Stream = IStream_To_RTL_MEMORY_STREAM(This);
343 
344  if (!Stats)
345  return STG_E_INVALIDPOINTER;
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  */
362 HRESULT
363 NTAPI
365  _In_ IStream *This,
367  _In_ ULONG Length,
369 {
374 
375  return E_NOTIMPL;
376 }
377 
378 /*
379  * @implemented
380  */
381 HRESULT
382 NTAPI
384  _In_ IStream *This,
386 {
389 
390  return E_NOTIMPL;
391 }
392 
393 /*
394  * @implemented
395  */
396 HRESULT
397 NTAPI
399  _In_ IStream *This,
400  _In_ ULONG CommitFlags)
401 {
403  UNREFERENCED_PARAMETER(CommitFlags);
404 
405  return E_NOTIMPL;
406 }
407 
408 /*
409  * @implemented
410  */
411 HRESULT
412 NTAPI
414  _In_ IStream *This)
415 {
417 
418  return E_NOTIMPL;
419 }
420 
421 /*
422  * @implemented
423  */
424 HRESULT
425 NTAPI
427  _In_ IStream *This,
430  _In_ ULONG LockType)
431 {
435  UNREFERENCED_PARAMETER(LockType);
436 
437  return E_NOTIMPL;
438 }
439 
440 /*
441  * @implemented
442  */
443 HRESULT
444 NTAPI
446  _In_ IStream *This,
449  _In_ ULONG LockType)
450 {
454  UNREFERENCED_PARAMETER(LockType);
455 
456  return E_NOTIMPL;
457 }
458 
459 /*
460  * @implemented
461  */
462 HRESULT
463 NTAPI
465  _In_ IStream *This,
466  _Outptr_ IStream **ResultStream)
467 {
469  UNREFERENCED_PARAMETER(ResultStream);
470 
471  return E_NOTIMPL;
472 }
473 
474 /*
475  * @implemented
476  */
477 NTSTATUS
478 NTAPI
482  _In_ SIZE_T Size)
483 {
485  _SEH2_TRY
486  {
488  }
492  {
494  }
495  _SEH2_END;
496  return Status;
497 }
_Must_inspect_result_ _In_ LONGLONG _In_ LONGLONG Amount
Definition: fsrtlfuncs.h:550
HRESULT NTAPI RtlUnlockMemoryStreamRegion(_In_ IStream *This, _In_ ULARGE_INTEGER Offset, _In_ ULARGE_INTEGER Length, _In_ ULONG LockType)
Definition: memstream.c:445
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesWritten
Definition: fltkernel.h:1293
#define REFIID
Definition: guiddef.h:113
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
_In_ ULONG _Out_writes_bytes_all_(Length) PUCHAR Buffer
Definition: ntddpcm.h:100
#define E_NOINTERFACE
Definition: winerror.h:2364
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
VOID NTAPI RtlInitOutOfProcessMemoryStream(_Out_ PRTL_MEMORY_STREAM Stream)
Definition: memstream.c:84
static PRTL_MEMORY_STREAM IStream_To_RTL_MEMORY_STREAM(_In_ IStream *Interface)
Definition: memstream.c:58
#define STG_E_INVALIDPOINTER
Definition: winerror.h:2571
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
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
unsigned char * PUCHAR
Definition: retypes.h:3
char CHAR
Definition: xmlstorage.h:175
LONG NTSTATUS
Definition: precomp.h:26
const struct IStreamVtbl RtlMemoryStreamVtbl
Definition: memstream.c:18
#define _Outptr_
Definition: no_sal2.h:396
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
_SEH2_TRY
Definition: create.c:4250
HRESULT NTAPI RtlQueryInterfaceMemoryStream(_In_ IStream *This, _In_ REFIID RequestedIid, _Outptr_ PVOID *ResultObject)
Definition: memstream.c:108
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:86
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
long LONG
Definition: pedump.c:60
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define E_INVALIDARG
Definition: ddrawi.h:101
smooth NULL
Definition: ftsmooth.c:416
#define _Out_writes_bytes_(size)
Definition: no_sal2.h:370
_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:426
#define _Out_
Definition: no_sal2.h:323
Definition: bufpool.h:45
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
HRESULT NTAPI RtlStatMemoryStream(_In_ IStream *This, _Out_ STATSTG *Stats, _In_ ULONG Flags)
Definition: memstream.c:337
#define _Out_opt_
Definition: no_sal2.h:339
IN PVOID IN PVOID IN USHORT IN USHORT IN PINTERFACE Interface
Definition: pci.h:359
HRESULT NTAPI RtlSetMemoryStreamSize(_In_ IStream *This, _In_ ULARGE_INTEGER NewSize)
Definition: memstream.c:383
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
LONG HRESULT
Definition: typedefs.h:77
uint64_t ULONGLONG
Definition: typedefs.h:65
const GUID IID_IUnknown
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:2875
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
_Must_inspect_result_ typedef _In_ ULONG _In_ BOOLEAN Target
Definition: iotypes.h:1067
NTSTATUS NTAPI NtReadVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, OUT PVOID Buffer, IN SIZE_T NumberOfBytesToRead, OUT PSIZE_T NumberOfBytesRead OPTIONAL)
Definition: virtual.c:2691
Definition: partlist.h:33
ULONG NTAPI RtlAddRefMemoryStream(_In_ IStream *This)
Definition: memstream.c:131
#define InterlockedDecrement
Definition: armddk.h:52
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
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
#define _In_reads_bytes_(size)
Definition: no_sal2.h:229
Status
Definition: gdiplustypes.h:24
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
#define _In_
Definition: no_sal2.h:204
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define S_OK
Definition: intsafe.h:59
_SEH2_END
Definition: create.c:4424
#define InterlockedIncrement
Definition: armddk.h:53
HRESULT NTAPI RtlCloneMemoryStream(_In_ IStream *This, _Outptr_ IStream **ResultStream)
Definition: memstream.c:464
#define E_NOTIMPL
Definition: ddrawi.h:99
HRESULT NTAPI RtlReadOutOfProcessMemoryStream(_In_ IStream *This, _Out_writes_bytes_(Length) PVOID Buffer, _In_ ULONG Length, _Out_opt_ PULONG BytesRead)
Definition: memstream.c:198
unsigned int * PULONG
Definition: retypes.h:1
#define min(a, b)
Definition: monoChain.cc:55
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
VOID NTAPI RtlInitMemoryStream(_Out_ PRTL_MEMORY_STREAM Stream)
Definition: memstream.c:72
HRESULT NTAPI RtlRevertMemoryStream(_In_ IStream *This)
Definition: memstream.c:413
const struct IStreamVtbl RtlOutOfProcessMemoryStreamVtbl
Definition: memstream.c:36
unsigned int ULONG
Definition: retypes.h:1
VOID NTAPI RtlFinalReleaseOutOfProcessMemoryStream(_In_ PRTL_MEMORY_STREAM Stream)
Definition: memstream.c:97
#define UNIMPLEMENTED
Definition: debug.h:114
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3167
HRESULT NTAPI RtlLockMemoryStreamRegion(_In_ IStream *This, _In_ ULARGE_INTEGER Offset, _In_ ULARGE_INTEGER Length, _In_ ULONG LockType)
Definition: memstream.c:426
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
HRESULT NTAPI RtlReadMemoryStream(_In_ IStream *This, _Out_writes_bytes_(Length) PVOID Buffer, _In_ ULONG Length, _Out_opt_ PULONG BytesRead)
Definition: memstream.c:166
#define STATUS_IN_PAGE_ERROR
Definition: ntstatus.h:229
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
HRESULT NTAPI RtlCommitMemoryStream(_In_ IStream *This, _In_ ULONG CommitFlags)
Definition: memstream.c:398
ULONG NTAPI RtlReleaseMemoryStream(_In_ IStream *This)
Definition: memstream.c:144
return STATUS_SUCCESS
Definition: btrfs.c:2745
_Inout_opt_ PUNICODE_STRING _Inout_opt_ PUNICODE_STRING Stream
Definition: fltkernel.h:1092
#define CONST
Definition: pedump.c:81
HRESULT NTAPI RtlWriteMemoryStream(_In_ IStream *This, _In_reads_bytes_(Length) CONST VOID *Buffer, _In_ ULONG Length, _Out_opt_ PULONG BytesWritten)
Definition: memstream.c:364
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ FLT_IO_OPERATION_FLAGS _Out_opt_ PULONG BytesRead
Definition: fltkernel.h:1255
LONGLONG QuadPart
Definition: typedefs.h:112
HRESULT NTAPI RtlSeekMemoryStream(_In_ IStream *This, _In_ LARGE_INTEGER RelativeOffset, _In_ ULONG Origin, _Out_opt_ PULARGE_INTEGER ResultOffset)
Definition: memstream.c:239