1 /* 2 * PROJECT: ReactOS api tests 3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory 4 * PURPOSE: Test for RtlReAllocateHeap 5 * PROGRAMMERS: Thomas Faber <thomas.faber@reactos.org> 6 */ 7 8 #include "precomp.h" 9 10 static 11 BOOLEAN 12 CheckBuffer( 13 PVOID Buffer, 14 SIZE_T Size, 15 UCHAR Value) 16 { 17 PUCHAR Array = Buffer; 18 SIZE_T i; 19 20 for (i = 0; i < Size; i++) 21 if (Array[i] != Value) 22 { 23 trace("Expected %x, found %x at offset %lu\n", Value, Array[i], (ULONG)i); 24 return FALSE; 25 } 26 return TRUE; 27 } 28 29 static 30 BOOLEAN 31 ReAllocBuffer( 32 PUCHAR *Buffer, 33 SIZE_T Size, 34 SIZE_T *OldSizePtr, 35 PCSTR Action) 36 { 37 PUCHAR NewBuffer; 38 SIZE_T OldSize = *OldSizePtr; 39 40 RtlFillMemory(*Buffer, OldSize, 0x7a); 41 NewBuffer = RtlReAllocateHeap(RtlGetProcessHeap(), 42 HEAP_ZERO_MEMORY, 43 *Buffer, 44 Size); 45 if (!NewBuffer) 46 { 47 skip("RtlReAllocateHeap failed for size %lu (%s)\n", Size, Action); 48 return FALSE; 49 } 50 *Buffer = NewBuffer; 51 ok_hex(RtlSizeHeap(RtlGetProcessHeap(), 0, NewBuffer), Size); 52 if (OldSize < Size) 53 { 54 ok(CheckBuffer(NewBuffer, OldSize, 0x7a), "CheckBuffer failed at size 0x%lx -> 0x%lx\n", OldSize, Size); 55 ok(CheckBuffer(NewBuffer + OldSize, Size - OldSize, 0), "HEAP_ZERO_MEMORY not respected for 0x%lx -> 0x%lx\n", OldSize, Size); 56 } 57 else 58 { 59 ok(CheckBuffer(NewBuffer, Size, 0x7a), "CheckBuffer failed at size 0x%lx -> 0x%lx\n", OldSize, Size); 60 } 61 *OldSizePtr = Size; 62 return TRUE; 63 } 64 65 START_TEST(RtlReAllocateHeap) 66 { 67 PUCHAR Buffer = NULL; 68 SIZE_T OldSize = 0; 69 SIZE_T Size; 70 BOOLEAN Continue = TRUE; 71 BOOLEAN Success; 72 PVOID UserValue; 73 ULONG UserFlags; 74 PVOID Buffer2; 75 76 OldSize = 0x100; 77 Buffer = RtlReAllocateHeap(RtlGetProcessHeap(), 78 HEAP_ZERO_MEMORY, 79 NULL, 80 OldSize); 81 ok(Buffer == NULL, "RtlReAllocateHeap succeeded for NULL\n"); 82 if (Buffer) 83 RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); 84 85 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 86 HEAP_ZERO_MEMORY, 87 OldSize); 88 if (!Buffer) 89 { 90 skip("RtlAllocateHeap failed for size %lu\n", OldSize); 91 return; 92 } 93 ok(CheckBuffer(Buffer, OldSize, 0), "HEAP_ZERO_MEMORY not respected for 0x%lx\n", OldSize); 94 95 for (Size = 0x78000; Size < 0x90000 && Continue; Size += 0x100) 96 { 97 Continue = ReAllocBuffer(&Buffer, Size, &OldSize, "growing"); 98 } 99 100 /* and back again */ 101 for (Size -= 0x100; Size >= 0x78000 && Continue; Size -= 0x100) 102 { 103 Continue = ReAllocBuffer(&Buffer, Size, &OldSize, "shrinking"); 104 } 105 RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); 106 107 /* Now make sure user flags/values get preserved */ 108 OldSize = 0x100; 109 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 110 HEAP_ZERO_MEMORY | HEAP_SETTABLE_USER_VALUE | HEAP_SETTABLE_USER_FLAG2, 111 OldSize); 112 if (!Buffer) 113 { 114 skip("RtlAllocateHeap failed for size %lu\n", OldSize); 115 return; 116 } 117 118 UserValue = InvalidPointer; 119 UserFlags = 0x55555555; 120 Success = RtlGetUserInfoHeap(RtlGetProcessHeap(), 121 0, 122 Buffer, 123 &UserValue, 124 &UserFlags); 125 ok(Success == TRUE, "RtlGetUserInfoHeap returned %u\n", Success); 126 ok(UserValue == NULL, "UserValue = %p\n", UserValue); 127 ok(UserFlags == HEAP_SETTABLE_USER_FLAG2, "UserFlags = %lx\n", UserFlags); 128 129 Success = RtlSetUserFlagsHeap(RtlGetProcessHeap(), 130 0, 131 Buffer, 132 HEAP_SETTABLE_USER_FLAG1 | HEAP_SETTABLE_USER_FLAG2, 133 HEAP_SETTABLE_USER_FLAG3); 134 ok(Success == TRUE, "RtlSetUserFlagsHeap returned %u\n", Success); 135 136 Success = RtlSetUserValueHeap(RtlGetProcessHeap(), 137 0, 138 Buffer, 139 &UserValue); 140 ok(Success == TRUE, "RtlSetUserValueHeap returned %u\n", Success); 141 142 UserValue = InvalidPointer; 143 UserFlags = 0x55555555; 144 Success = RtlGetUserInfoHeap(RtlGetProcessHeap(), 145 0, 146 Buffer, 147 &UserValue, 148 &UserFlags); 149 ok(Success == TRUE, "RtlGetUserInfoHeap returned %u\n", Success); 150 ok(UserValue == &UserValue, "UserValue = %p, expected %p\n", UserValue, &UserValue); 151 ok(UserFlags == HEAP_SETTABLE_USER_FLAG3, "UserFlags = %lx\n", UserFlags); 152 153 /* shrink (preserves flags) */ 154 Buffer2 = RtlReAllocateHeap(RtlGetProcessHeap(), 155 HEAP_REALLOC_IN_PLACE_ONLY | HEAP_SETTABLE_USER_FLAG2, 156 Buffer, 157 OldSize / 2); 158 ok(Buffer2 == Buffer, "New Buffer is %p, expected %p\n", Buffer2, Buffer); 159 if (Buffer2) Buffer = Buffer2; 160 UserValue = InvalidPointer; 161 UserFlags = 0x55555555; 162 Success = RtlGetUserInfoHeap(RtlGetProcessHeap(), 163 0, 164 Buffer, 165 &UserValue, 166 &UserFlags); 167 ok(Success == TRUE, "RtlGetUserInfoHeap returned %u\n", Success); 168 ok(UserValue == &UserValue, "UserValue = %p, expected %p\n", UserValue, &UserValue); 169 ok(UserFlags == HEAP_SETTABLE_USER_FLAG3, "UserFlags = %lx\n", UserFlags); 170 171 /* grow (overwrites flags) */ 172 Buffer2 = RtlReAllocateHeap(RtlGetProcessHeap(), 173 HEAP_REALLOC_IN_PLACE_ONLY | HEAP_SETTABLE_USER_FLAG1, 174 Buffer, 175 OldSize / 4 * 3); 176 ok(Buffer2 == Buffer, "New Buffer is %p, expected %p\n", Buffer2, Buffer); 177 if (Buffer2) Buffer = Buffer2; 178 UserValue = InvalidPointer; 179 UserFlags = 0x55555555; 180 Success = RtlGetUserInfoHeap(RtlGetProcessHeap(), 181 0, 182 Buffer, 183 &UserValue, 184 &UserFlags); 185 ok(Success == TRUE, "RtlGetUserInfoHeap returned %u\n", Success); 186 ok(UserValue == &UserValue, "UserValue = %p, expected %p\n", UserValue, &UserValue); 187 ok(UserFlags == HEAP_SETTABLE_USER_FLAG1, "UserFlags = %lx\n", UserFlags); 188 189 RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); 190 } 191