2 * PROJECT: ReactOS api tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Test for the Rtl*MemoryStream* series of functions
5 * PROGRAMMER: David Quintana <gigaherz@gmail.com>
11 #include <ndk/rtlfuncs.h>
15 ULONG finalReleaseCallCount
= 0;
19 CustomFinalReleaseMemoryStream(PRTL_MEMORY_STREAM stream
)
21 finalReleaseCallCount
++;
22 trace("FinalRelease CALLED.\n");
27 CustomFinalReleaseOutOfProcessMemoryStream(PRTL_MEMORY_STREAM stream
)
29 finalReleaseCallCount
++;
30 trace("FinalRelease CALLED.\n");
31 RtlFinalReleaseOutOfProcessMemoryStream(stream
);
34 BOOL
CompareStructsAndSaveForLater(PRTL_MEMORY_STREAM pold
, PRTL_MEMORY_STREAM pnew
, PSTR at
)
39 if (pold
->Vtbl
!= pnew
->Vtbl
) { if (equal
) { trace("%s: \n", at
); equal
= FALSE
; } trace("Vtbl changed from %p to %p\n", pold
->Vtbl
, pnew
->Vtbl
);}
40 if (pold
->RefCount
!= pnew
->RefCount
) { if (equal
) { trace("%s: \n", at
); equal
= FALSE
; } trace("RefCount changed from %ld to %ld\n", pold
->RefCount
, pnew
->RefCount
); }
41 if (pold
->Unk1
!= pnew
->Unk1
) { if (equal
) { trace("%s: \n", at
); equal
= FALSE
; } trace("Unk1 changed from %lu to %lu\n", pold
->Unk1
, pnew
->Unk1
); }
42 if (pold
->Current
!= pnew
->Current
) { if (equal
) { trace("%s: \n", at
); equal
= FALSE
; } trace("Current changed from %p to %p\n", pold
->Current
, pnew
->Current
); }
43 if (pold
->Start
!= pnew
->Start
) { if (equal
) { trace("%s: \n", at
); equal
= FALSE
; } trace("Start changed from %p to %p\n", pold
->Start
, pnew
->Start
); }
44 if (pold
->End
!= pnew
->End
) { if (equal
) { trace("%s: \n", at
); equal
= FALSE
; } trace("End changed from %p to %p\n", pold
->End
, pnew
->End
); }
45 if (pold
->FinalRelease
!= pnew
->FinalRelease
) { if (equal
) { trace("%s: \n", at
); equal
= FALSE
; } trace("FinalRelease changed from %p to %p\n", pold
->FinalRelease
, pnew
->FinalRelease
); }
46 if (pold
->ProcessHandle
!= pnew
->ProcessHandle
) { if (equal
) { trace("%s: \n", at
); equal
= FALSE
; } trace("ProcessHandle changed from %p to %p\n", pold
->ProcessHandle
, pnew
->ProcessHandle
); }
49 pold
->Vtbl
= pnew
->Vtbl
;
50 pold
->RefCount
= pnew
->RefCount
;
51 pold
->Unk1
= pnew
->Unk1
;
52 pold
->Current
= pnew
->Current
;
53 pold
->Start
= pnew
->Start
;
54 pold
->End
= pnew
->End
;
55 pold
->FinalRelease
= pnew
->FinalRelease
;
56 pold
->ProcessHandle
= pnew
->ProcessHandle
;
68 RTL_MEMORY_STREAM stream
;
69 RTL_MEMORY_STREAM previous
;
79 finalReleaseCallCount
= 0;
81 for (i
= 0; i
< sizeof(buffer2
); i
++)
83 buffer2
[i
] = i
% UCHAR_MAX
;
86 memset(&stream
, 0x90, sizeof(stream
));
87 memset(&previous
, 0x00, sizeof(previous
));
90 RtlInitMemoryStream(NULL
);
91 EndSeh(STATUS_ACCESS_VIOLATION
);
94 RtlInitMemoryStream(&stream
);
95 EndSeh(STATUS_SUCCESS
);
97 CompareStructsAndSaveForLater(&previous
, &stream
, "After init");
99 ok(stream
.RefCount
== 0, "RefCount has a wrong value: %ld (expected %d).\n", stream
.RefCount
, 0);
101 stream
.Current
= buffer2
;
102 stream
.Start
= buffer2
;
103 stream
.End
= buffer2
+ sizeof(buffer2
);
104 stream
.FinalRelease
= CustomFinalReleaseMemoryStream
;
106 CompareStructsAndSaveForLater(&previous
, &stream
, "After assigning");
109 IStream_QueryInterface((struct IStream
*)&stream
, NULL
, NULL
);
110 EndSeh(STATUS_ACCESS_VIOLATION
);
113 IStream_QueryInterface((struct IStream
*)&stream
, &IID_IStream
, NULL
);
114 EndSeh(STATUS_ACCESS_VIOLATION
);
117 IStream_QueryInterface((struct IStream
*)&stream
, NULL
, (void**)&istream
);
118 EndSeh(STATUS_ACCESS_VIOLATION
);
121 res
= IStream_QueryInterface((struct IStream
*)&stream
, &IID_IStream
, (void**)&istream
);
122 ok(res
== S_OK
, "QueryInterface to IStream returned wrong hResult: 0x%08lx.\n", res
);
123 ok(stream
.RefCount
== 2, "RefCount has a wrong value: %ld (expected %d).\n", stream
.RefCount
, 2);
124 EndSeh(STATUS_SUCCESS
);
126 CompareStructsAndSaveForLater(&previous
, &stream
, "After QueryInterface");
129 res
= IStream_Stat(istream
, NULL
, 0);
130 ok(res
== STG_E_INVALIDPOINTER
, "Stat to IStream returned wrong hResult: 0x%08lx.\n", res
);
131 EndSeh(STATUS_SUCCESS
);
134 res
= IStream_Stat(istream
, &stat
, STATFLAG_NONAME
);
135 ok(res
== S_OK
, "Stat to IStream returned wrong hResult: 0x%08lx.\n", res
);
136 EndSeh(STATUS_SUCCESS
);
138 ok(stream
.Current
== buffer2
,
139 "stream.Current points to the wrong address 0x%p (expected 0x%p)\n",
140 stream
.Current
, buffer2
);
141 ok(stream
.Start
== buffer2
, "stream.Start was changed unexpectedly\n");
142 ok(stream
.End
== buffer2
+ sizeof(buffer2
), "stream.End was changed unexpectedly\n");
144 ok(stat
.cbSize
.QuadPart
== ((PUCHAR
)stream
.End
- (PUCHAR
)stream
.Start
),
145 "stat.cbSize has the wrong value %I64u (expected %d)\n",
146 stat
.cbSize
.QuadPart
, (PUCHAR
)stream
.End
- (PUCHAR
)stream
.Start
);
148 CompareStructsAndSaveForLater(&previous
, &stream
, "After Stat");
151 res
= IStream_AddRef(istream
);
152 ok(res
== 3, "AddRef to IStream returned wrong hResult: %ld.\n", res
);
153 EndSeh(STATUS_SUCCESS
);
156 res
= IStream_AddRef(istream
);
157 ok(res
== 4, "AddRef to IStream returned wrong hResult: %ld.\n", res
);
158 EndSeh(STATUS_SUCCESS
);
161 res
= IStream_Release(istream
);
162 ok(res
== 3, "Release to IStream returned wrong hResult: %ld.\n", res
);
163 EndSeh(STATUS_SUCCESS
);
166 res
= IStream_AddRef(istream
);
167 ok(res
== 4, "AddRef to IStream returned wrong hResult: %ld.\n", res
);
168 EndSeh(STATUS_SUCCESS
);
171 res
= IStream_Release(istream
);
172 ok(res
== 3, "Release to IStream returned wrong hResult: %ld.\n", res
);
173 EndSeh(STATUS_SUCCESS
);
176 res
= IStream_Release(istream
);
177 ok(res
== 2, "Release to IStream returned wrong hResult: %ld.\n", res
);
178 EndSeh(STATUS_SUCCESS
);
180 CompareStructsAndSaveForLater(&previous
, &stream
, "After AddRef");
183 res
= IStream_Read(istream
, NULL
, 0, &bytesRead
);
184 ok(res
== S_OK
, "Read to IStream returned wrong hResult: 0x%08lx.\n", res
);
185 EndSeh(STATUS_SUCCESS
);
188 res
= IStream_Read(istream
, buffer
, 40, NULL
);
189 ok(res
== S_OK
, "Read to IStream returned wrong hResult: 0x%08lx.\n", res
);
190 EndSeh(STATUS_ACCESS_VIOLATION
);
193 res
= IStream_Read(istream
, buffer
+ 40, 39, &bytesRead
);
194 ok(res
== S_OK
, "Read to IStream returned wrong hResult: 0x%08lx.\n", res
);
195 EndSeh(STATUS_SUCCESS
);
200 for (i
= 0; i
< bytesRead
; i
++)
202 ok(buffer
[i
] == i
, "Buffer[%lu] contains a wrong number %u (expected %lu).\n", i
, buffer
[i
], i
);
206 ok(stream
.Current
== buffer2
+ 79,
207 "stream.Current points to the wrong address 0x%p (expected 0x%p)\n",
208 stream
.Current
, buffer2
);
209 ok(stream
.Start
== buffer2
, "stream.Start was changed unexpectedly\n");
210 ok(stream
.End
== buffer2
+ sizeof(buffer2
), "stream.End was changed unexpectedly\n");
212 CompareStructsAndSaveForLater(&previous
, &stream
, "After Read 1");
214 size
.QuadPart
= 0x9090909090909090ull
;
218 res
= IStream_Seek(istream
, move
, STREAM_SEEK_END
, &size
);
219 ok(res
== STG_E_INVALIDPOINTER
, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res
);
220 ok(size
.QuadPart
== 0x9090909090909090ull
, "Seek modified the new location in an error (0x%08lx,0x%08lx).\n", size
.HighPart
, size
.LowPart
);
221 EndSeh(STATUS_SUCCESS
);
225 res
= IStream_Seek(istream
, move
, STREAM_SEEK_END
, &size
);
226 ok(res
== S_OK
, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res
);
227 ok(size
.QuadPart
== (PUCHAR
)stream
.End
- (PUCHAR
)stream
.Start
, "Seek new location unexpected value: 0x%08lx.\n", size
.LowPart
);
228 EndSeh(STATUS_SUCCESS
);
230 size
.QuadPart
= 0x9090909090909090ull
;
234 res
= IStream_Seek(istream
, move
, STREAM_SEEK_END
, &size
);
235 ok(res
== S_OK
, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res
);
236 ok(size
.QuadPart
== (PUCHAR
)stream
.End
- (PUCHAR
)stream
.Start
- 1, "Seek new location unexpected value: 0x%08lx.\n", size
.LowPart
);
237 EndSeh(STATUS_SUCCESS
);
239 size
.QuadPart
= 0x9090909090909090ull
;
243 res
= IStream_Seek(istream
, move
, STREAM_SEEK_END
, &size
);
244 ok(res
== S_OK
, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res
);
245 ok(size
.QuadPart
== (PUCHAR
)stream
.End
- (PUCHAR
)stream
.Start
- 2, "Seek new location unexpected value: 0x%08lx.\n", size
.LowPart
);
246 EndSeh(STATUS_SUCCESS
);
248 size
.QuadPart
= 0x9090909090909090ull
;
252 res
= IStream_Seek(istream
, move
, STREAM_SEEK_SET
, &size
);
253 ok(res
== STG_E_INVALIDPOINTER
, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res
);
254 ok(size
.QuadPart
== 0x9090909090909090ull
, "Seek modified the new location in an error.\n");
255 EndSeh(STATUS_SUCCESS
);
258 move
.QuadPart
= 4000;
259 res
= IStream_Seek(istream
, move
, STREAM_SEEK_SET
, &size
);
260 ok(res
== STG_E_INVALIDPOINTER
, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res
);
261 ok(size
.QuadPart
== 0x9090909090909090ull
, "Seek modified the new location in an error.\n");
262 EndSeh(STATUS_SUCCESS
);
265 move
.QuadPart
= 0x100000000ull
;
266 res
= IStream_Seek(istream
, move
, STREAM_SEEK_SET
, &size
);
268 ok(res
== STG_E_INVALIDPOINTER
, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res
);
269 ok(size
.QuadPart
== 0x9090909090909090ull
, "Seek modified the new location in an error (0x%08lx,0x%08lx).\n", size
.HighPart
, size
.LowPart
);
271 ok(res
== S_OK
, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res
);
272 ok(size
.QuadPart
== 0, "Seek new location unexpected value: 0x%08lx.\n", size
.LowPart
);
274 EndSeh(STATUS_SUCCESS
);
279 res
= IStream_Seek(istream
, move
, STREAM_SEEK_SET
, &size
);
280 ok(res
== S_OK
, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res
);
281 ok(size
.QuadPart
== 0, "Seek new location unexpected value: 0x%08lx.\n", size
.LowPart
);
282 EndSeh(STATUS_SUCCESS
);
285 size
.QuadPart
= 0x9090909090909090ull
;
289 res
= IStream_Seek(istream
, move
, STREAM_SEEK_CUR
, &size
);
290 ok(res
== STG_E_INVALIDPOINTER
, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res
);
291 ok(size
.QuadPart
== 0x9090909090909090ull
, "Seek modified the new location in an error (0x%08lx,0x%08lx).\n", size
.HighPart
, size
.LowPart
);
292 EndSeh(STATUS_SUCCESS
);
295 move
.QuadPart
= 0x100000000ull
;
296 res
= IStream_Seek(istream
, move
, STREAM_SEEK_CUR
, &size
);
298 ok(res
== STG_E_INVALIDPOINTER
, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res
);
299 ok(size
.QuadPart
== 0x9090909090909090ull
, "Seek modified the new location in an error (0x%08lx,0x%08lx).\n", size
.HighPart
, size
.LowPart
);
301 ok(res
== S_OK
, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res
);
302 ok(size
.QuadPart
== 0, "Seek new location unexpected value: 0x%08lx.\n", size
.LowPart
);
304 EndSeh(STATUS_SUCCESS
);
308 res
= IStream_Seek(istream
, move
, STREAM_SEEK_SET
, &size
);
309 ok(res
== S_OK
, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res
);
310 EndSeh(STATUS_SUCCESS
);
312 ok(size
.QuadPart
== 40,
313 "Seek returned wrong offset %I64u (expected %d)\n",
316 ok(stream
.Current
== buffer2
+ 40,
317 "stream.Current points to the wrong address 0x%p (expected 0x%p)\n",
318 stream
.Current
, buffer2
);
319 ok(stream
.Start
== buffer2
, "stream.Start was changed unexpectedly\n");
320 ok(stream
.End
== buffer2
+ sizeof(buffer2
), "stream.End was changed unexpectedly\n");
322 CompareStructsAndSaveForLater(&previous
, &stream
, "After Seek");
324 res
= IStream_Read(istream
, buffer
, sizeof(buffer
), &bytesRead
);
326 ok(res
== S_OK
, "Read to IStream returned wrong hResult: 0x%08lx.\n", res
);
330 for (i
= 0; i
< bytesRead
; i
++)
332 ok(buffer
[i
] == (i
+ 40), "Buffer[%lu] contains a wrong number %u (expected %lu).\n", i
, buffer
[i
], i
+ 40);
336 ok(stream
.Current
== buffer2
+ 40 + sizeof(buffer
),
337 "stream.Current points to the wrong address 0x%p (expected 0x%p)\n",
338 stream
.Current
, buffer2
);
339 ok(stream
.Start
== buffer2
, "stream.Start was changed unexpectedly\n");
340 ok(stream
.End
== buffer2
+ sizeof(buffer2
), "stream.End was changed unexpectedly\n");
342 CompareStructsAndSaveForLater(&previous
, &stream
, "After Read 2");
344 res
= IStream_Release(istream
);
346 ok(res
== 1, "Release to IStream returned wrong hResult: 0x%08lx.\n", res
);
348 ok(stream
.RefCount
== 1, "RefCount has a wrong value: %ld (expected %d).\n", stream
.RefCount
, 1);
350 res
= IStream_Release(istream
);
352 ok(res
== S_OK
, "Release to IStream returned wrong hResult: 0x%08lx.\n", res
);
354 ok(stream
.RefCount
== 0, "RefCount has a wrong value: %ld (expected %d).\n", stream
.RefCount
, 0);
356 ok(finalReleaseCallCount
== 1, "FinalRelease was called %lu times instead of 1.\n", finalReleaseCallCount
);
359 void test_OutOfProcess()
367 RTL_MEMORY_STREAM stream
;
368 RTL_MEMORY_STREAM previous
;
378 finalReleaseCallCount
= 0;
380 for (i
= 0; i
< sizeof(buffer2
); i
++)
382 buffer2
[i
] = i
% UCHAR_MAX
;
385 memset(&stream
, 0x90, sizeof(stream
));
386 memset(&previous
, 0x00, sizeof(previous
));
388 process
= GetCurrentProcess();
390 RtlInitOutOfProcessMemoryStream(&stream
);
392 ok(stream
.FinalRelease
== RtlFinalReleaseOutOfProcessMemoryStream
,
393 "stream.FinalRelease unexpected %p != %p.\n",
394 stream
.FinalRelease
, RtlFinalReleaseOutOfProcessMemoryStream
);
396 ok(stream
.RefCount
== 0, "RefCount has a wrong value: %ld (expected %d).\n", stream
.RefCount
, 0);
398 CompareStructsAndSaveForLater(&previous
, &stream
, "After init");
400 stream
.Current
= buffer2
;
401 stream
.Start
= buffer2
;
402 stream
.End
= buffer2
+ sizeof(buffer2
);
403 stream
.ProcessHandle
= process
;
404 stream
.FinalRelease
= CustomFinalReleaseOutOfProcessMemoryStream
;
406 CompareStructsAndSaveForLater(&previous
, &stream
, "After assigning");
408 res
= IStream_QueryInterface((struct IStream
*)&stream
, &IID_IStream
, (void**)&istream
);
410 ok(res
== S_OK
, "QueryInterface to IStream returned wrong hResult: 0x%08lx.\n", res
);
412 ok(stream
.RefCount
== 1, "RefCount has a wrong value: %ld (expected %d).\n", stream
.RefCount
, 1);
414 ok(stream
.ProcessHandle
== process
,
415 "ProcessHandle changed unexpectedly: 0x%p (expected 0x%p)\n",
416 stream
.ProcessHandle
, process
);
418 CompareStructsAndSaveForLater(&previous
, &stream
, "After QueryInterface");
420 res
= IStream_Stat(istream
, &stat
, STATFLAG_NONAME
);
422 ok(res
== S_OK
, "Stat to IStream returned wrong hResult: 0x%08lx.\n", res
);
424 ok(stream
.Current
== buffer2
,
425 "stream.Current points to the wrong address 0x%p (expected 0x%p)\n",
426 stream
.Current
, buffer2
);
427 ok(stream
.Start
== buffer2
, "stream.Start was changed unexpectedly\n");
428 ok(stream
.End
== buffer2
+ sizeof(buffer2
), "stream.End was changed unexpectedly\n");
429 ok(stream
.ProcessHandle
== process
,
430 "ProcessHandle changed unexpectedly: 0x%p (expected 0x%p)\n",
431 stream
.ProcessHandle
, process
);
433 ok(stat
.cbSize
.QuadPart
== ((PUCHAR
)stream
.End
- (PUCHAR
)stream
.Start
),
434 "stat.cbSize has the wrong value %I64u (expected %d)\n",
435 stat
.cbSize
.QuadPart
, (PUCHAR
)stream
.End
- (PUCHAR
)stream
.Start
);
437 CompareStructsAndSaveForLater(&previous
, &stream
, "After Stat");
439 res
= IStream_Read(istream
, buffer
, sizeof(buffer
), &bytesRead
);
441 ok(res
== S_OK
, "Read to IStream returned wrong hResult: 0x%08lx.\n", res
);
445 for (i
= 0; i
< bytesRead
; i
++)
447 ok(buffer
[i
] == i
, "Buffer[%lu] contains a wrong number %u (expected %lu).\n", i
, buffer
[i
], i
);
451 ok(stream
.Current
== buffer2
+ sizeof(buffer
),
452 "stream.Current points to the wrong address 0x%p (expected 0x%p)\n",
453 stream
.Current
, buffer2
);
454 ok(stream
.Start
== buffer2
, "stream.Start was changed unexpectedly\n");
455 ok(stream
.End
== buffer2
+ sizeof(buffer2
), "stream.End was changed unexpectedly\n");
456 ok(stream
.ProcessHandle
== process
,
457 "ProcessHandle changed unexpectedly: 0x%p (expected 0x%p)\n",
458 stream
.ProcessHandle
, process
);
460 CompareStructsAndSaveForLater(&previous
, &stream
, "After Read 1");
464 res
= IStream_Seek(istream
, move
, STREAM_SEEK_SET
, &size
);
466 ok(res
== S_OK
, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res
);
468 ok(size
.QuadPart
== 40,
469 "Seek returned wrong offset %I64u (expected %d)\n",
472 ok(stream
.Current
== buffer2
+ 40,
473 "stream.Current points to the wrong address 0x%p (expected 0x%p)\n",
474 stream
.Current
, buffer2
);
475 ok(stream
.Start
== buffer2
, "stream.Start was changed unexpectedly\n");
476 ok(stream
.End
== buffer2
+ sizeof(buffer2
), "stream.End was changed unexpectedly\n");
477 ok(stream
.ProcessHandle
== process
,
478 "ProcessHandle changed unexpectedly: 0x%p (expected 0x%p)\n",
479 stream
.ProcessHandle
, process
);
481 CompareStructsAndSaveForLater(&previous
, &stream
, "After Seek");
483 res
= IStream_Read(istream
, buffer
, sizeof(buffer
), &bytesRead
);
485 ok(res
== S_OK
, "Read to IStream returned wrong hResult: 0x%08lx.\n", res
);
489 for (i
= 0; i
< bytesRead
; i
++)
491 ok(buffer
[i
] == (i
+ 40), "Buffer[%lu] contains a wrong number %u (expected %lu).\n", i
, buffer
[i
], i
+ 40);
495 ok(stream
.Current
== buffer2
+ 40 + sizeof(buffer
),
496 "stream.Current points to the wrong address 0x%p (expected 0x%p)\n",
497 stream
.Current
, buffer2
);
498 ok(stream
.Start
== buffer2
, "stream.Start was changed unexpectedly\n");
499 ok(stream
.End
== buffer2
+ sizeof(buffer2
), "stream.End was changed unexpectedly\n");
500 ok(stream
.ProcessHandle
== process
,
501 "ProcessHandle changed unexpectedly: 0x%p (expected 0x%p)\n",
502 stream
.ProcessHandle
, process
);
504 CompareStructsAndSaveForLater(&previous
, &stream
, "After Read 2");
506 res
= IStream_Release(istream
);
508 ok(res
== S_OK
, "Release to IStream returned wrong hResult: 0x%08lx.\n", res
);
510 ok(stream
.RefCount
== 0, "RefCount has a wrong value: %ld (expected %d).\n", stream
.RefCount
, 0);
512 ok(finalReleaseCallCount
== 1, "FinalRelease was called %lu times instead of 1.\n", finalReleaseCallCount
);
515 START_TEST(RtlMemoryStream
)