1 /* 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> 6 */ 7 8 #include "precomp.h" 9 10 #define COBJMACROS 11 #include <ole2.h> 12 #include <wtypes.h> 13 14 ULONG finalReleaseCallCount = 0; 15 16 VOID 17 NTAPI 18 CustomFinalReleaseMemoryStream(PRTL_MEMORY_STREAM stream) 19 { 20 finalReleaseCallCount++; 21 trace("FinalRelease CALLED.\n"); 22 } 23 24 VOID 25 NTAPI 26 CustomFinalReleaseOutOfProcessMemoryStream(PRTL_MEMORY_STREAM stream) 27 { 28 finalReleaseCallCount++; 29 trace("FinalRelease CALLED.\n"); 30 RtlFinalReleaseOutOfProcessMemoryStream(stream); 31 } 32 33 BOOL CompareStructsAndSaveForLater(PRTL_MEMORY_STREAM pold, PRTL_MEMORY_STREAM pnew, PSTR at) 34 { 35 BOOL equal = TRUE; 36 37 // Compare 38 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);} 39 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); } 40 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); } 41 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); } 42 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); } 43 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); } 44 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); } 45 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); } 46 47 // Save 48 pold->Vtbl = pnew->Vtbl; 49 pold->RefCount = pnew->RefCount; 50 pold->Unk1 = pnew->Unk1; 51 pold->Current = pnew->Current; 52 pold->Start = pnew->Start; 53 pold->End = pnew->End; 54 pold->FinalRelease = pnew->FinalRelease; 55 pold->ProcessHandle = pnew->ProcessHandle; 56 57 return equal; 58 } 59 60 void test_InProcess() 61 { 62 LARGE_INTEGER move; 63 ULARGE_INTEGER size; 64 HRESULT res; 65 ULONG i; 66 67 RTL_MEMORY_STREAM stream; 68 RTL_MEMORY_STREAM previous; 69 70 IStream * istream; 71 72 UCHAR buffer[80]; 73 UCHAR buffer2[180]; 74 ULONG bytesRead; 75 76 STATSTG stat; 77 78 finalReleaseCallCount = 0; 79 80 for (i = 0; i < sizeof(buffer2); i++) 81 { 82 buffer2[i] = i % UCHAR_MAX; 83 } 84 85 memset(&stream, 0x90, sizeof(stream)); 86 memset(&previous, 0x00, sizeof(previous)); 87 88 StartSeh() 89 RtlInitMemoryStream(NULL); 90 EndSeh(STATUS_ACCESS_VIOLATION); 91 92 StartSeh() 93 RtlInitMemoryStream(&stream); 94 EndSeh(STATUS_SUCCESS); 95 96 CompareStructsAndSaveForLater(&previous, &stream, "After init"); 97 98 ok(stream.RefCount == 0, "RefCount has a wrong value: %ld (expected %d).\n", stream.RefCount, 0); 99 100 stream.Current = buffer2; 101 stream.Start = buffer2; 102 stream.End = buffer2 + sizeof(buffer2); 103 stream.FinalRelease = CustomFinalReleaseMemoryStream; 104 105 CompareStructsAndSaveForLater(&previous, &stream, "After assigning"); 106 107 StartSeh() 108 IStream_QueryInterface((struct IStream*)&stream, NULL, NULL); 109 EndSeh(STATUS_ACCESS_VIOLATION); 110 111 StartSeh() 112 IStream_QueryInterface((struct IStream*)&stream, &IID_IStream, NULL); 113 EndSeh(STATUS_ACCESS_VIOLATION); 114 115 StartSeh() 116 IStream_QueryInterface((struct IStream*)&stream, NULL, (void**)&istream); 117 EndSeh(STATUS_ACCESS_VIOLATION); 118 119 StartSeh() 120 res = IStream_QueryInterface((struct IStream*)&stream, &IID_IStream, (void**)&istream); 121 ok(res == S_OK, "QueryInterface to IStream returned wrong hResult: 0x%08lx.\n", res); 122 ok(stream.RefCount == 2, "RefCount has a wrong value: %ld (expected %d).\n", stream.RefCount, 2); 123 EndSeh(STATUS_SUCCESS); 124 125 CompareStructsAndSaveForLater(&previous, &stream, "After QueryInterface"); 126 127 StartSeh() 128 res = IStream_Stat(istream, NULL, 0); 129 ok(res == STG_E_INVALIDPOINTER, "Stat to IStream returned wrong hResult: 0x%08lx.\n", res); 130 EndSeh(STATUS_SUCCESS); 131 132 StartSeh() 133 res = IStream_Stat(istream, &stat, STATFLAG_NONAME); 134 ok(res == S_OK, "Stat to IStream returned wrong hResult: 0x%08lx.\n", res); 135 EndSeh(STATUS_SUCCESS); 136 137 ok(stream.Current == buffer2, 138 "stream.Current points to the wrong address 0x%p (expected 0x%p)\n", 139 stream.Current, buffer2); 140 ok(stream.Start == buffer2, "stream.Start was changed unexpectedly\n"); 141 ok(stream.End == buffer2 + sizeof(buffer2), "stream.End was changed unexpectedly\n"); 142 143 ok(stat.cbSize.QuadPart == ((PUCHAR)stream.End - (PUCHAR)stream.Start), 144 "stat.cbSize has the wrong value %I64u (expected %d)\n", 145 stat.cbSize.QuadPart, (PUCHAR)stream.End - (PUCHAR)stream.Start); 146 147 CompareStructsAndSaveForLater(&previous, &stream, "After Stat"); 148 149 StartSeh() 150 res = IStream_AddRef(istream); 151 ok(res == 3, "AddRef to IStream returned wrong hResult: %ld.\n", res); 152 EndSeh(STATUS_SUCCESS); 153 154 StartSeh() 155 res = IStream_AddRef(istream); 156 ok(res == 4, "AddRef to IStream returned wrong hResult: %ld.\n", res); 157 EndSeh(STATUS_SUCCESS); 158 159 StartSeh() 160 res = IStream_Release(istream); 161 ok(res == 3, "Release to IStream returned wrong hResult: %ld.\n", res); 162 EndSeh(STATUS_SUCCESS); 163 164 StartSeh() 165 res = IStream_AddRef(istream); 166 ok(res == 4, "AddRef to IStream returned wrong hResult: %ld.\n", res); 167 EndSeh(STATUS_SUCCESS); 168 169 StartSeh() 170 res = IStream_Release(istream); 171 ok(res == 3, "Release to IStream returned wrong hResult: %ld.\n", res); 172 EndSeh(STATUS_SUCCESS); 173 174 StartSeh() 175 res = IStream_Release(istream); 176 ok(res == 2, "Release to IStream returned wrong hResult: %ld.\n", res); 177 EndSeh(STATUS_SUCCESS); 178 179 CompareStructsAndSaveForLater(&previous, &stream, "After AddRef"); 180 181 StartSeh() 182 res = IStream_Read(istream, NULL, 0, &bytesRead); 183 ok(res == S_OK, "Read to IStream returned wrong hResult: 0x%08lx.\n", res); 184 EndSeh(STATUS_SUCCESS); 185 186 StartSeh() 187 res = IStream_Read(istream, buffer, 40, NULL); 188 ok(res == S_OK, "Read to IStream returned wrong hResult: 0x%08lx.\n", res); 189 EndSeh(STATUS_ACCESS_VIOLATION); 190 191 StartSeh() 192 res = IStream_Read(istream, buffer + 40, 39, &bytesRead); 193 ok(res == S_OK, "Read to IStream returned wrong hResult: 0x%08lx.\n", res); 194 EndSeh(STATUS_SUCCESS); 195 196 if (SUCCEEDED(res)) 197 { 198 bytesRead += 40; 199 for (i = 0; i < bytesRead; i++) 200 { 201 ok(buffer[i] == i, "Buffer[%lu] contains a wrong number %u (expected %lu).\n", i, buffer[i], i); 202 } 203 } 204 205 ok(stream.Current == buffer2 + 79, 206 "stream.Current points to the wrong address 0x%p (expected 0x%p)\n", 207 stream.Current, buffer2); 208 ok(stream.Start == buffer2, "stream.Start was changed unexpectedly\n"); 209 ok(stream.End == buffer2 + sizeof(buffer2), "stream.End was changed unexpectedly\n"); 210 211 CompareStructsAndSaveForLater(&previous, &stream, "After Read 1"); 212 213 size.QuadPart = 0x9090909090909090ull; 214 215 StartSeh() 216 move.QuadPart = -1; 217 res = IStream_Seek(istream, move, STREAM_SEEK_END, &size); 218 ok(res == STG_E_INVALIDPOINTER, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res); 219 ok(size.QuadPart == 0x9090909090909090ull, "Seek modified the new location in an error (0x%08lx,0x%08lx).\n", size.HighPart, size.LowPart); 220 EndSeh(STATUS_SUCCESS); 221 222 StartSeh() 223 move.QuadPart = 0; 224 res = IStream_Seek(istream, move, STREAM_SEEK_END, &size); 225 ok(res == S_OK, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res); 226 ok(size.QuadPart == (PUCHAR)stream.End - (PUCHAR)stream.Start, "Seek new location unexpected value: 0x%08lx.\n", size.LowPart); 227 EndSeh(STATUS_SUCCESS); 228 229 size.QuadPart = 0x9090909090909090ull; 230 231 StartSeh() 232 move.QuadPart = 1; 233 res = IStream_Seek(istream, move, STREAM_SEEK_END, &size); 234 ok(res == S_OK, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res); 235 ok(size.QuadPart == (PUCHAR)stream.End - (PUCHAR)stream.Start - 1, "Seek new location unexpected value: 0x%08lx.\n", size.LowPart); 236 EndSeh(STATUS_SUCCESS); 237 238 size.QuadPart = 0x9090909090909090ull; 239 240 StartSeh() 241 move.QuadPart = 2; 242 res = IStream_Seek(istream, move, STREAM_SEEK_END, &size); 243 ok(res == S_OK, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res); 244 ok(size.QuadPart == (PUCHAR)stream.End - (PUCHAR)stream.Start - 2, "Seek new location unexpected value: 0x%08lx.\n", size.LowPart); 245 EndSeh(STATUS_SUCCESS); 246 247 size.QuadPart = 0x9090909090909090ull; 248 249 StartSeh() 250 move.QuadPart = -20; 251 res = IStream_Seek(istream, move, STREAM_SEEK_SET, &size); 252 ok(res == STG_E_INVALIDPOINTER, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res); 253 ok(size.QuadPart == 0x9090909090909090ull, "Seek modified the new location in an error.\n"); 254 EndSeh(STATUS_SUCCESS); 255 256 StartSeh() 257 move.QuadPart = 4000; 258 res = IStream_Seek(istream, move, STREAM_SEEK_SET, &size); 259 ok(res == STG_E_INVALIDPOINTER, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res); 260 ok(size.QuadPart == 0x9090909090909090ull, "Seek modified the new location in an error.\n"); 261 EndSeh(STATUS_SUCCESS); 262 263 StartSeh() 264 move.QuadPart = 0x100000000ull; 265 res = IStream_Seek(istream, move, STREAM_SEEK_SET, &size); 266 #ifdef _WIN64 267 ok(res == STG_E_INVALIDPOINTER, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res); 268 ok(size.QuadPart == 0x9090909090909090ull, "Seek modified the new location in an error (0x%08lx,0x%08lx).\n", size.HighPart, size.LowPart); 269 #else 270 ok(res == S_OK, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res); 271 ok(size.QuadPart == 0, "Seek new location unexpected value: 0x%08lx.\n", size.LowPart); 272 #endif 273 EndSeh(STATUS_SUCCESS); 274 275 #ifdef _WIN64 276 StartSeh() 277 move.QuadPart = 0; 278 res = IStream_Seek(istream, move, STREAM_SEEK_SET, &size); 279 ok(res == S_OK, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res); 280 ok(size.QuadPart == 0, "Seek new location unexpected value: 0x%08lx.\n", size.LowPart); 281 EndSeh(STATUS_SUCCESS); 282 #endif 283 284 size.QuadPart = 0x9090909090909090ull; 285 286 StartSeh() 287 move.QuadPart = -20; 288 res = IStream_Seek(istream, move, STREAM_SEEK_CUR, &size); 289 ok(res == STG_E_INVALIDPOINTER, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res); 290 ok(size.QuadPart == 0x9090909090909090ull, "Seek modified the new location in an error (0x%08lx,0x%08lx).\n", size.HighPart, size.LowPart); 291 EndSeh(STATUS_SUCCESS); 292 293 StartSeh() 294 move.QuadPart = 0x100000000ull; 295 res = IStream_Seek(istream, move, STREAM_SEEK_CUR, &size); 296 #ifdef _WIN64 297 ok(res == STG_E_INVALIDPOINTER, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res); 298 ok(size.QuadPart == 0x9090909090909090ull, "Seek modified the new location in an error (0x%08lx,0x%08lx).\n", size.HighPart, size.LowPart); 299 #else 300 ok(res == S_OK, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res); 301 ok(size.QuadPart == 0, "Seek new location unexpected value: 0x%08lx.\n", size.LowPart); 302 #endif 303 EndSeh(STATUS_SUCCESS); 304 305 StartSeh() 306 move.QuadPart = 40; 307 res = IStream_Seek(istream, move, STREAM_SEEK_SET, &size); 308 ok(res == S_OK, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res); 309 EndSeh(STATUS_SUCCESS); 310 311 ok(size.QuadPart == 40, 312 "Seek returned wrong offset %I64u (expected %d)\n", 313 size.QuadPart, 40); 314 315 ok(stream.Current == buffer2 + 40, 316 "stream.Current points to the wrong address 0x%p (expected 0x%p)\n", 317 stream.Current, buffer2); 318 ok(stream.Start == buffer2, "stream.Start was changed unexpectedly\n"); 319 ok(stream.End == buffer2 + sizeof(buffer2), "stream.End was changed unexpectedly\n"); 320 321 CompareStructsAndSaveForLater(&previous, &stream, "After Seek"); 322 323 res = IStream_Read(istream, buffer, sizeof(buffer), &bytesRead); 324 325 ok(res == S_OK, "Read to IStream returned wrong hResult: 0x%08lx.\n", res); 326 327 if (SUCCEEDED(res)) 328 { 329 for (i = 0; i < bytesRead; i++) 330 { 331 ok(buffer[i] == (i + 40), "Buffer[%lu] contains a wrong number %u (expected %lu).\n", i, buffer[i], i + 40); 332 } 333 } 334 335 ok(stream.Current == buffer2 + 40 + sizeof(buffer), 336 "stream.Current points to the wrong address 0x%p (expected 0x%p)\n", 337 stream.Current, buffer2); 338 ok(stream.Start == buffer2, "stream.Start was changed unexpectedly\n"); 339 ok(stream.End == buffer2 + sizeof(buffer2), "stream.End was changed unexpectedly\n"); 340 341 CompareStructsAndSaveForLater(&previous, &stream, "After Read 2"); 342 343 res = IStream_Release(istream); 344 345 ok(res == 1, "Release to IStream returned wrong hResult: 0x%08lx.\n", res); 346 347 ok(stream.RefCount == 1, "RefCount has a wrong value: %ld (expected %d).\n", stream.RefCount, 1); 348 349 res = IStream_Release(istream); 350 351 ok(res == S_OK, "Release to IStream returned wrong hResult: 0x%08lx.\n", res); 352 353 ok(stream.RefCount == 0, "RefCount has a wrong value: %ld (expected %d).\n", stream.RefCount, 0); 354 355 ok(finalReleaseCallCount == 1, "FinalRelease was called %lu times instead of 1.\n", finalReleaseCallCount); 356 } 357 358 void test_OutOfProcess() 359 { 360 LARGE_INTEGER move; 361 ULARGE_INTEGER size; 362 HRESULT res; 363 HANDLE process; 364 ULONG i; 365 366 RTL_MEMORY_STREAM stream; 367 RTL_MEMORY_STREAM previous; 368 369 IStream * istream; 370 371 UCHAR buffer[80]; 372 UCHAR buffer2[180]; 373 ULONG bytesRead; 374 375 STATSTG stat; 376 377 finalReleaseCallCount = 0; 378 379 for (i = 0; i < sizeof(buffer2); i++) 380 { 381 buffer2[i] = i % UCHAR_MAX; 382 } 383 384 memset(&stream, 0x90, sizeof(stream)); 385 memset(&previous, 0x00, sizeof(previous)); 386 387 process = GetCurrentProcess(); 388 389 RtlInitOutOfProcessMemoryStream(&stream); 390 391 ok(stream.FinalRelease == RtlFinalReleaseOutOfProcessMemoryStream, 392 "stream.FinalRelease unexpected %p != %p.\n", 393 stream.FinalRelease, RtlFinalReleaseOutOfProcessMemoryStream); 394 395 ok(stream.RefCount == 0, "RefCount has a wrong value: %ld (expected %d).\n", stream.RefCount, 0); 396 397 CompareStructsAndSaveForLater(&previous, &stream, "After init"); 398 399 stream.Current = buffer2; 400 stream.Start = buffer2; 401 stream.End = buffer2 + sizeof(buffer2); 402 stream.ProcessHandle = process; 403 stream.FinalRelease = CustomFinalReleaseOutOfProcessMemoryStream; 404 405 CompareStructsAndSaveForLater(&previous, &stream, "After assigning"); 406 407 res = IStream_QueryInterface((struct IStream*)&stream, &IID_IStream, (void**)&istream); 408 409 ok(res == S_OK, "QueryInterface to IStream returned wrong hResult: 0x%08lx.\n", res); 410 411 ok(stream.RefCount == 1, "RefCount has a wrong value: %ld (expected %d).\n", stream.RefCount, 1); 412 413 ok(stream.ProcessHandle == process, 414 "ProcessHandle changed unexpectedly: 0x%p (expected 0x%p)\n", 415 stream.ProcessHandle, process); 416 417 CompareStructsAndSaveForLater(&previous, &stream, "After QueryInterface"); 418 419 res = IStream_Stat(istream, &stat, STATFLAG_NONAME); 420 421 ok(res == S_OK, "Stat to IStream returned wrong hResult: 0x%08lx.\n", res); 422 423 ok(stream.Current == buffer2, 424 "stream.Current points to the wrong address 0x%p (expected 0x%p)\n", 425 stream.Current, buffer2); 426 ok(stream.Start == buffer2, "stream.Start was changed unexpectedly\n"); 427 ok(stream.End == buffer2 + sizeof(buffer2), "stream.End was changed unexpectedly\n"); 428 ok(stream.ProcessHandle == process, 429 "ProcessHandle changed unexpectedly: 0x%p (expected 0x%p)\n", 430 stream.ProcessHandle, process); 431 432 ok(stat.cbSize.QuadPart == ((PUCHAR)stream.End - (PUCHAR)stream.Start), 433 "stat.cbSize has the wrong value %I64u (expected %d)\n", 434 stat.cbSize.QuadPart, (PUCHAR)stream.End - (PUCHAR)stream.Start); 435 436 CompareStructsAndSaveForLater(&previous, &stream, "After Stat"); 437 438 res = IStream_Read(istream, buffer, sizeof(buffer), &bytesRead); 439 440 ok(res == S_OK, "Read to IStream returned wrong hResult: 0x%08lx.\n", res); 441 442 if (SUCCEEDED(res)) 443 { 444 for (i = 0; i < bytesRead; i++) 445 { 446 ok(buffer[i] == i, "Buffer[%lu] contains a wrong number %u (expected %lu).\n", i, buffer[i], i); 447 } 448 } 449 450 ok(stream.Current == buffer2 + sizeof(buffer), 451 "stream.Current points to the wrong address 0x%p (expected 0x%p)\n", 452 stream.Current, buffer2); 453 ok(stream.Start == buffer2, "stream.Start was changed unexpectedly\n"); 454 ok(stream.End == buffer2 + sizeof(buffer2), "stream.End was changed unexpectedly\n"); 455 ok(stream.ProcessHandle == process, 456 "ProcessHandle changed unexpectedly: 0x%p (expected 0x%p)\n", 457 stream.ProcessHandle, process); 458 459 CompareStructsAndSaveForLater(&previous, &stream, "After Read 1"); 460 461 move.QuadPart = 40; 462 463 res = IStream_Seek(istream, move, STREAM_SEEK_SET, &size); 464 465 ok(res == S_OK, "Seek to IStream returned wrong hResult: 0x%08lx.\n", res); 466 467 ok(size.QuadPart == 40, 468 "Seek returned wrong offset %I64u (expected %d)\n", 469 size.QuadPart, 40); 470 471 ok(stream.Current == buffer2 + 40, 472 "stream.Current points to the wrong address 0x%p (expected 0x%p)\n", 473 stream.Current, buffer2); 474 ok(stream.Start == buffer2, "stream.Start was changed unexpectedly\n"); 475 ok(stream.End == buffer2 + sizeof(buffer2), "stream.End was changed unexpectedly\n"); 476 ok(stream.ProcessHandle == process, 477 "ProcessHandle changed unexpectedly: 0x%p (expected 0x%p)\n", 478 stream.ProcessHandle, process); 479 480 CompareStructsAndSaveForLater(&previous, &stream, "After Seek"); 481 482 res = IStream_Read(istream, buffer, sizeof(buffer), &bytesRead); 483 484 ok(res == S_OK, "Read to IStream returned wrong hResult: 0x%08lx.\n", res); 485 486 if (SUCCEEDED(res)) 487 { 488 for (i = 0; i < bytesRead; i++) 489 { 490 ok(buffer[i] == (i + 40), "Buffer[%lu] contains a wrong number %u (expected %lu).\n", i, buffer[i], i + 40); 491 } 492 } 493 494 ok(stream.Current == buffer2 + 40 + sizeof(buffer), 495 "stream.Current points to the wrong address 0x%p (expected 0x%p)\n", 496 stream.Current, buffer2); 497 ok(stream.Start == buffer2, "stream.Start was changed unexpectedly\n"); 498 ok(stream.End == buffer2 + sizeof(buffer2), "stream.End was changed unexpectedly\n"); 499 ok(stream.ProcessHandle == process, 500 "ProcessHandle changed unexpectedly: 0x%p (expected 0x%p)\n", 501 stream.ProcessHandle, process); 502 503 CompareStructsAndSaveForLater(&previous, &stream, "After Read 2"); 504 505 res = IStream_Release(istream); 506 507 ok(res == S_OK, "Release to IStream returned wrong hResult: 0x%08lx.\n", res); 508 509 ok(stream.RefCount == 0, "RefCount has a wrong value: %ld (expected %d).\n", stream.RefCount, 0); 510 511 ok(finalReleaseCallCount == 1, "FinalRelease was called %lu times instead of 1.\n", finalReleaseCallCount); 512 } 513 514 START_TEST(RtlMemoryStream) 515 { 516 test_InProcess(); 517 test_OutOfProcess(); 518 } 519