ReactOS 0.4.16-dev-297-gc569aee
heap.c File Reference
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winternl.h"
#include "wine/test.h"
Include dependency graph for heap.c:

Go to the source code of this file.

Classes

struct  heap_layout
 

Macros

#define MAGIC_DEAD   0xdeadbeef
 
#define HEAP_PAGE_ALLOCS   0x01000000
 
#define HEAP_VALIDATE   0x10000000
 
#define HEAP_VALIDATE_ALL   0x20000000
 
#define HEAP_VALIDATE_PARAMS   0x40000000
 

Functions

static BOOL (WINAPI *pHeapQueryInformation)(HANDLE
 
static ULONG (WINAPI *pRtlGetNtGlobalFlags)(void)
 
static SIZE_T resize_9x (SIZE_T size)
 
static void test_sized_HeapAlloc (int nbytes)
 
static void test_sized_HeapReAlloc (int nbytes1, int nbytes2)
 
static void test_heap (void)
 
static void test_HeapCreate (void)
 
static void test_GlobalAlloc (void)
 
static void test_LocalAlloc (void)
 
static void test_obsolete_flags (void)
 
static void test_HeapQueryInformation (void)
 
static void test_heap_checks (DWORD flags)
 
static void test_debug_heap (const char *argv0, DWORD flags)
 
static DWORD heap_flags_from_global_flag (DWORD flag)
 
static void test_child_heap (const char *arg)
 
static void test_GetPhysicallyInstalledSystemMemory (void)
 
 START_TEST (heap)
 

Variables

static HEAP_INFORMATION_CLASS
 
static PVOID
 
static SIZE_T
 
static PSIZE_T
 

Macro Definition Documentation

◆ HEAP_PAGE_ALLOCS

#define HEAP_PAGE_ALLOCS   0x01000000

Definition at line 36 of file heap.c.

◆ HEAP_VALIDATE

#define HEAP_VALIDATE   0x10000000

Definition at line 37 of file heap.c.

◆ HEAP_VALIDATE_ALL

#define HEAP_VALIDATE_ALL   0x20000000

Definition at line 38 of file heap.c.

◆ HEAP_VALIDATE_PARAMS

#define HEAP_VALIDATE_PARAMS   0x40000000

Definition at line 39 of file heap.c.

◆ MAGIC_DEAD

#define MAGIC_DEAD   0xdeadbeef

Definition at line 33 of file heap.c.

Function Documentation

◆ BOOL()

static BOOL ( WINAPI pHeapQueryInformation)
static

◆ heap_flags_from_global_flag()

static DWORD heap_flags_from_global_flag ( DWORD  flag)
static

Definition at line 1114 of file heap.c.

1115{
1116 DWORD ret = 0;
1117
1130 return ret;
1131}
unsigned long DWORD
Definition: ntddk_ex.h:95
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean flag
Definition: glfuncs.h:52
#define FLG_HEAP_DISABLE_COALESCING
Definition: pstypes.h:80
#define FLG_HEAP_PAGE_ALLOCS
Definition: pstypes.h:84
#define FLG_HEAP_ENABLE_FREE_CHECK
Definition: pstypes.h:61
#define FLG_HEAP_VALIDATE_PARAMETERS
Definition: pstypes.h:62
#define FLG_HEAP_ENABLE_TAIL_CHECK
Definition: pstypes.h:60
#define FLG_HEAP_VALIDATE_ALL
Definition: pstypes.h:63
#define HEAP_VALIDATE
Definition: heap.c:37
#define HEAP_VALIDATE_PARAMS
Definition: heap.c:39
#define HEAP_VALIDATE_ALL
Definition: heap.c:38
#define HEAP_PAGE_ALLOCS
Definition: heap.c:36
#define HEAP_FREE_CHECKING_ENABLED
Definition: nt_native.h:1698
#define HEAP_DISABLE_COALESCE_ON_FREE
Definition: nt_native.h:1699
#define HEAP_TAIL_CHECKING_ENABLED
Definition: nt_native.h:1697
#define HEAP_GROWABLE
Definition: nt_native.h:1693
int ret

Referenced by test_child_heap().

◆ resize_9x()

static SIZE_T resize_9x ( SIZE_T  size)
static

Definition at line 53 of file heap.c.

54{
55 DWORD dwSizeAligned = (size + 3) & ~3;
56 return max(dwSizeAligned, 12); /* at least 12 bytes */
57}
GLsizeiptr size
Definition: glext.h:5919
#define max(a, b)
Definition: svc.c:63

Referenced by test_heap().

◆ START_TEST()

START_TEST ( heap  )

Definition at line 1219 of file heap.c.

1220{
1221 int argc;
1222 char **argv;
1223
1224 pRtlGetNtGlobalFlags = (void *)GetProcAddress( GetModuleHandleA("ntdll.dll"), "RtlGetNtGlobalFlags" );
1225
1227 if (argc >= 3)
1228 {
1229 test_child_heap( argv[2] );
1230 return;
1231 }
1232
1233 test_heap();
1238
1239 /* Test both short and very long blocks */
1241 test_sized_HeapAlloc(1 << 20);
1242 test_sized_HeapReAlloc(1, 100);
1243 test_sized_HeapReAlloc(1, (1 << 20));
1244 test_sized_HeapReAlloc((1 << 20), (2 << 20));
1245 test_sized_HeapReAlloc((1 << 20), 1);
1246
1249
1250 if (pRtlGetNtGlobalFlags)
1251 {
1252 test_debug_heap( argv[0], 0 );
1262 test_debug_heap( argv[0], 0xdeadbeef );
1263 }
1264 else win_skip( "RtlGetNtGlobalFlags not found, skipping heap debug tests\n" );
1265}
static int argc
Definition: ServiceArgs.c:12
#define GetProcAddress(x, y)
Definition: compat.h:753
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
#define FLG_HEAP_ENABLE_TAGGING
Definition: pstypes.h:66
#define FLG_POOL_ENABLE_TAGGING
Definition: pstypes.h:65
#define FLG_HEAP_ENABLE_TAG_BY_DLL
Definition: pstypes.h:70
static void test_GetPhysicallyInstalledSystemMemory(void)
Definition: heap.c:1187
static void test_child_heap(const char *arg)
Definition: heap.c:1133
static void test_heap(void)
Definition: heap.c:82
static void test_GlobalAlloc(void)
Definition: heap.c:633
static void test_LocalAlloc(void)
Definition: heap.c:715
static void test_debug_heap(const char *argv0, DWORD flags)
Definition: heap.c:1065
static void test_sized_HeapReAlloc(int nbytes1, int nbytes2)
Definition: heap.c:69
static void test_HeapCreate(void)
Definition: heap.c:524
static void test_HeapQueryInformation(void)
Definition: heap.c:843
static void test_sized_HeapAlloc(int nbytes)
Definition: heap.c:59
static void test_obsolete_flags(void)
Definition: heap.c:795
#define argv
Definition: mplay32.c:18
#define win_skip
Definition: test.h:163
int winetest_get_mainargs(char ***pargv)

◆ test_child_heap()

static void test_child_heap ( const char arg)
static

Definition at line 1133 of file heap.c.

1134{
1135 struct heap_layout *heap = GetProcessHeap();
1136 DWORD expected = strtoul( arg, 0, 16 );
1137 DWORD expect_heap;
1138
1139 if (expected == 0xdeadbeef) /* expected value comes from Session Manager global flags */
1140 {
1141 HKEY hkey;
1142 expected = 0;
1143 if (!RegOpenKeyA( HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Session Manager", &hkey ))
1144 {
1145 char buffer[32];
1146 DWORD type, size = sizeof(buffer);
1147
1148 if (!RegQueryValueExA( hkey, "GlobalFlag", 0, &type, (BYTE *)buffer, &size ))
1149 {
1150 if (type == REG_DWORD) expected = *(DWORD *)buffer;
1151 else if (type == REG_SZ) expected = strtoul( buffer, 0, 16 );
1152 }
1153 RegCloseKey( hkey );
1154 }
1155 }
1156 if (expected && !pRtlGetNtGlobalFlags()) /* not working on NT4 */
1157 {
1158 win_skip( "global flags not set\n" );
1159 return;
1160 }
1161
1162 ok( pRtlGetNtGlobalFlags() == expected,
1163 "%s: got global flags %08x expected %08x\n", arg, pRtlGetNtGlobalFlags(), expected );
1164
1165 expect_heap = heap_flags_from_global_flag( expected );
1166
1167 if (!(heap->flags & HEAP_GROWABLE) || heap->pattern == 0xffeeffee) /* vista layout */
1168 {
1169 ok( (heap->flags & ~HEAP_GROWABLE) == 0, "%s: got heap flags %08x\n", arg, heap->flags );
1170 }
1171 else if (heap->pattern == 0xeeeeeeee && heap->flags == 0xeeeeeeee)
1172 {
1173 ok( expected & FLG_HEAP_PAGE_ALLOCS, "%s: got heap flags 0xeeeeeeee without page alloc\n", arg );
1174 }
1175 else
1176 {
1177 ok( heap->flags == (expect_heap | HEAP_GROWABLE),
1178 "%s: got heap flags %08x expected %08x\n", arg, heap->flags, expect_heap );
1179 ok( heap->force_flags == (expect_heap & ~0x18000080),
1180 "%s: got heap force flags %08x expected %08x\n", arg, heap->force_flags, expect_heap );
1181 expect_heap = heap->flags;
1182 }
1183
1184 test_heap_checks( expect_heap );
1185}
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
Definition: utclib.c:696
#define ok(value,...)
Definition: atltest.h:57
#define RegCloseKey(hKey)
Definition: registry.h:49
LONG WINAPI RegOpenKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3234
LONG WINAPI RegQueryValueExA(_In_ HKEY hkeyorg, _In_ LPCSTR name, _In_ LPDWORD reserved, _Out_opt_ LPDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ LPDWORD count)
Definition: reg.c:4009
#define GetProcessHeap()
Definition: compat.h:736
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint buffer
Definition: glext.h:5915
#define REG_SZ
Definition: layer.c:22
BOOL expected
Definition: store.c:2063
static DWORD heap_flags_from_global_flag(DWORD flag)
Definition: heap.c:1114
static void test_heap_checks(DWORD flags)
Definition: heap.c:895
#define REG_DWORD
Definition: sdbapi.c:596
static HANDLE heap
Definition: heap.c:65
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
unsigned char BYTE
Definition: xxhash.c:193

Referenced by START_TEST().

◆ test_debug_heap()

static void test_debug_heap ( const char argv0,
DWORD  flags 
)
static

Definition at line 1065 of file heap.c.

1066{
1067 char keyname[MAX_PATH];
1068 char buffer[MAX_PATH];
1071 BOOL ret;
1072 DWORD err;
1073 HKEY hkey;
1074 const char *basename;
1075
1076 if ((basename = strrchr( argv0, '\\' ))) basename++;
1077 else basename = argv0;
1078
1079 sprintf( keyname, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\%s",
1080 basename );
1081 if (!strcmp( keyname + strlen(keyname) - 3, ".so" )) keyname[strlen(keyname) - 3] = 0;
1082
1083 err = RegCreateKeyA( HKEY_LOCAL_MACHINE, keyname, &hkey );
1084 if (err == ERROR_ACCESS_DENIED)
1085 {
1086 skip("Not authorized to change the image file execution options\n");
1087 return;
1088 }
1089 ok( !err, "failed to create '%s' error %u\n", keyname, err );
1090 if (err) return;
1091
1092 if (flags == 0xdeadbeef) /* magic value for unsetting it */
1093 RegDeleteValueA( hkey, "GlobalFlag" );
1094 else
1095 RegSetValueExA( hkey, "GlobalFlag", 0, REG_DWORD, (BYTE *)&flags, sizeof(flags) );
1096
1097 memset( &startup, 0, sizeof(startup) );
1098 startup.cb = sizeof(startup);
1099
1100 sprintf( buffer, "%s heap.c 0x%x", argv0, flags );
1102 ok( ret, "failed to create child process error %u\n", GetLastError() );
1103 if (ret)
1104 {
1106 CloseHandle( info.hThread );
1107 CloseHandle( info.hProcess );
1108 }
1109 RegDeleteValueA( hkey, "GlobalFlag" );
1110 RegCloseKey( hkey );
1112}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
static void startup(void)
#define skip(...)
Definition: atltest.h:64
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
LONG WINAPI RegCreateKeyA(HKEY hKey, LPCSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1179
LONG WINAPI RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData)
Definition: reg.c:4799
LONG WINAPI RegDeleteValueA(HKEY hKey, LPCSTR lpValueName)
Definition: reg.c:2287
LONG WINAPI RegDeleteKeyA(_In_ HKEY hKey, _In_ LPCSTR lpSubKey)
Definition: reg.c:1224
#define CloseHandle
Definition: compat.h:739
#define MAX_PATH
Definition: compat.h:34
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4747
static void basename(LPCWSTR path, LPWSTR name)
Definition: profile.c:38
unsigned int BOOL
Definition: ntddk_ex.h:94
GLbitfield flags
Definition: glext.h:7161
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define err(...)
_CRT_RESTORE_GCC_WARNINGS _CRT_DISABLE_GCC_WARNINGS _Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
void winetest_wait_child_process(HANDLE process)
#define memset(x, y, z)
Definition: compat.h:39
static char argv0[MAX_PATH]
Definition: shlexec.c:49
DWORD WINAPI GetLastError(void)
Definition: except.c:1042

Referenced by START_TEST().

◆ test_GetPhysicallyInstalledSystemMemory()

static void test_GetPhysicallyInstalledSystemMemory ( void  )
static

Definition at line 1187 of file heap.c.

1188{
1189 HMODULE kernel32 = GetModuleHandleA("kernel32.dll");
1190 MEMORYSTATUSEX memstatus;
1191 ULONGLONG total_memory;
1192 BOOL ret;
1193
1194 pGetPhysicallyInstalledSystemMemory = (void *)GetProcAddress(kernel32, "GetPhysicallyInstalledSystemMemory");
1195 if (!pGetPhysicallyInstalledSystemMemory)
1196 {
1197 win_skip("GetPhysicallyInstalledSystemMemory is not available\n");
1198 return;
1199 }
1200
1201 SetLastError(0xdeadbeef);
1202 ret = pGetPhysicallyInstalledSystemMemory(NULL);
1203 ok(!ret, "GetPhysicallyInstalledSystemMemory should fail\n");
1205 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1206
1207 total_memory = 0;
1208 ret = pGetPhysicallyInstalledSystemMemory(&total_memory);
1209 ok(ret, "GetPhysicallyInstalledSystemMemory unexpectedly failed\n");
1210 ok(total_memory != 0, "expected total_memory != 0\n");
1211
1212 memstatus.dwLength = sizeof(memstatus);
1213 ret = GlobalMemoryStatusEx(&memstatus);
1214 ok(ret, "GlobalMemoryStatusEx unexpectedly failed\n");
1215 ok(total_memory >= memstatus.ullTotalPhys / 1024,
1216 "expected total_memory >= memstatus.ullTotalPhys / 1024\n");
1217}
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
BOOL NTAPI GlobalMemoryStatusEx(LPMEMORYSTATUSEX lpBuffer)
Definition: heapmem.c:1272
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by START_TEST().

◆ test_GlobalAlloc()

static void test_GlobalAlloc ( void  )
static

Definition at line 633 of file heap.c.

634{
635 ULONG memchunk;
636 HGLOBAL mem1,mem2,mem2a,mem2b;
637 UCHAR *mem2ptr;
638 UINT i;
639 BOOL error;
640 memchunk=100000;
641
643 /* Check that a normal alloc works */
644 mem1=GlobalAlloc(0,memchunk);
645 ok(mem1!=NULL,"GlobalAlloc failed\n");
646 if(mem1) {
647 ok(GlobalSize(mem1)>=memchunk, "GlobalAlloc should return a big enough memory block\n");
648 }
649
650 /* Check that a 'zeroing' alloc works */
651 mem2=GlobalAlloc(GMEM_ZEROINIT,memchunk);
652 ok(mem2!=NULL,"GlobalAlloc failed: error=%d\n",GetLastError());
653 if(mem2) {
654 ok(GlobalSize(mem2)>=memchunk,"GlobalAlloc should return a big enough memory block\n");
655 mem2ptr=GlobalLock(mem2);
656 ok(mem2ptr==mem2,"GlobalLock should have returned the same memory as was allocated\n");
657 if(mem2ptr) {
658 error=FALSE;
659 for(i=0;i<memchunk;i++) {
660 if(mem2ptr[i]!=0) {
661 error=TRUE;
662 }
663 }
664 ok(!error,"GlobalAlloc should have zeroed out its allocated memory\n");
665 }
666 }
667 /* Check that GlobalReAlloc works */
668 /* Check that we can change GMEM_FIXED to GMEM_MOVEABLE */
670 if(mem2a!=NULL) {
671 mem2=mem2a;
672 mem2ptr=GlobalLock(mem2a);
673 ok(mem2ptr!=NULL && !GlobalUnlock(mem2a)&&GetLastError()==NO_ERROR,
674 "Converting from FIXED to MOVEABLE didn't REALLY work\n");
675 }
676
677 /* Check that ReAllocing memory works as expected */
678 mem2a=GlobalReAlloc(mem2,2*memchunk,GMEM_MOVEABLE | GMEM_ZEROINIT);
679 ok(mem2a!=NULL,"GlobalReAlloc failed\n");
680 if(mem2a) {
681 ok(GlobalSize(mem2a)>=2*memchunk,"GlobalReAlloc failed\n");
682 mem2ptr=GlobalLock(mem2a);
683 ok(mem2ptr!=NULL,"GlobalLock Failed\n");
684 if(mem2ptr) {
685 error=FALSE;
686 for(i=0;i<memchunk;i++) {
687 if(mem2ptr[memchunk+i]!=0) {
688 error=TRUE;
689 }
690 }
691 ok(!error,"GlobalReAlloc should have zeroed out its allocated memory\n");
692
693 /* Check that GlobalHandle works */
694 mem2b=GlobalHandle(mem2ptr);
695 ok(mem2b==mem2a,"GlobalHandle didn't return the correct memory handle %p/%p for %p\n",
696 mem2a, mem2b, mem2ptr);
697 /* Check that we can't discard locked memory */
698 mem2b=GlobalDiscard(mem2a);
699 if(mem2b==NULL) {
700 ok(!GlobalUnlock(mem2a) && GetLastError()==NO_ERROR,"GlobalUnlock Failed\n");
701 }
702 }
703 }
704 if(mem1) {
705 ok(GlobalFree(mem1)==NULL,"GlobalFree failed\n");
706 }
707 if(mem2a) {
708 ok(GlobalFree(mem2a)==NULL,"GlobalFree failed\n");
709 } else {
710 ok(GlobalFree(mem2)==NULL,"GlobalFree failed\n");
711 }
712}
#define NO_ERROR
Definition: dderror.h:5
#define TRUE
Definition: types.h:120
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
HGLOBAL NTAPI GlobalHandle(LPCVOID pMem)
Definition: heapmem.c:705
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
HGLOBAL NTAPI GlobalReAlloc(HGLOBAL hMem, SIZE_T dwBytes, UINT uFlags)
Definition: heapmem.c:825
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
#define error(str)
Definition: mkdosfs.c:1605
unsigned int UINT
Definition: ndis.h:50
uint32_t ULONG
Definition: typedefs.h:59
#define GMEM_ZEROINIT
Definition: winbase.h:332
#define GMEM_MODIFY
Definition: winbase.h:321
#define GMEM_MOVEABLE
Definition: winbase.h:320
#define GlobalDiscard(m)
Definition: winbase.h:2603
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by START_TEST().

◆ test_heap()

static void test_heap ( void  )
static

Definition at line 82 of file heap.c.

83{
84 LPVOID mem;
85 LPVOID msecond;
86 DWORD res;
87 UINT flags;
88 HGLOBAL gbl;
89 HGLOBAL hsecond;
90 SIZE_T size, size2;
91 const SIZE_T max_size = 1024, init_size = 10;
92 /* use function pointers to avoid warnings for invalid parameter tests */
93 LPVOID (WINAPI *pHeapAlloc)(HANDLE,DWORD,SIZE_T);
94 LPVOID (WINAPI *pHeapReAlloc)(HANDLE,DWORD,LPVOID,SIZE_T);
95
96 pHeapAlloc = (void *)GetProcAddress( GetModuleHandleA("kernel32"), "HeapAlloc" );
97 pHeapReAlloc = (void *)GetProcAddress( GetModuleHandleA("kernel32"), "HeapReAlloc" );
98
99 /* Heap*() functions */
100 mem = HeapAlloc(GetProcessHeap(), 0, 0);
101 ok(mem != NULL, "memory not allocated for size 0\n");
103
104 mem = HeapReAlloc(GetProcessHeap(), 0, NULL, 10);
105 ok(mem == NULL, "memory allocated by HeapReAlloc\n");
106
107 for (size = 0; size <= 256; size++)
108 {
109 SIZE_T heap_size;
111 heap_size = HeapSize(GetProcessHeap(), 0, mem);
112 ok(heap_size == size || heap_size == resize_9x(size),
113 "HeapSize returned %lu instead of %lu or %lu\n", heap_size, size, resize_9x(size));
115 }
116
117 /* test some border cases of HeapAlloc and HeapReAlloc */
118 mem = HeapAlloc(GetProcessHeap(), 0, 0);
119 ok(mem != NULL, "memory not allocated for size 0\n");
120 msecond = pHeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, mem, ~(SIZE_T)0 - 7);
121 ok(msecond == NULL, "HeapReAlloc(~0 - 7) should have failed\n");
122 msecond = pHeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, mem, ~(SIZE_T)0);
123 ok(msecond == NULL, "HeapReAlloc(~0) should have failed\n");
125 mem = pHeapAlloc(GetProcessHeap(), 0, ~(SIZE_T)0);
126 ok(mem == NULL, "memory allocated for size ~0\n");
127 mem = HeapAlloc(GetProcessHeap(), 0, 17);
128 msecond = HeapReAlloc(GetProcessHeap(), 0, mem, 0);
129 ok(msecond != NULL, "HeapReAlloc(0) should have succeeded\n");
130 size = HeapSize(GetProcessHeap(), 0, msecond);
131 ok(size == 0 || broken(size == 1) /* some vista and win7 */,
132 "HeapSize should have returned 0 instead of %lu\n", size);
133 HeapFree(GetProcessHeap(), 0, msecond);
134
135 /* large blocks must be 16-byte aligned */
136 mem = HeapAlloc(GetProcessHeap(), 0, 512 * 1024);
137 ok( mem != NULL, "failed for size 512K\n" );
138 ok( (ULONG_PTR)mem % 16 == 0 || broken((ULONG_PTR)mem % 16) /* win9x */,
139 "512K block not 16-byte aligned\n" );
141
142 /* Global*() functions */
143 gbl = GlobalAlloc(GMEM_MOVEABLE, 0);
144 ok(gbl != NULL, "global memory not allocated for size 0\n");
145
146 gbl = GlobalReAlloc(gbl, 10, GMEM_MOVEABLE);
147 ok(gbl != NULL, "Can't realloc global memory\n");
148 size = GlobalSize(gbl);
149 ok(size >= 10 && size <= 16, "Memory not resized to size 10, instead size=%ld\n", size);
150
151 gbl = GlobalReAlloc(gbl, 0, GMEM_MOVEABLE);
152 ok(gbl != NULL, "GlobalReAlloc should not fail on size 0\n");
153
154 size = GlobalSize(gbl);
155 ok(size == 0, "Memory not resized to size 0, instead size=%ld\n", size);
156 ok(GlobalFree(gbl) == NULL, "Memory not freed\n");
157 size = GlobalSize(gbl);
158 ok(size == 0, "Memory should have been freed, size=%ld\n", size);
159
160 gbl = GlobalReAlloc(0, 10, GMEM_MOVEABLE);
161 ok(gbl == NULL, "global realloc allocated memory\n");
162
163 /* GlobalLock / GlobalUnlock with a valid handle */
164 gbl = GlobalAlloc(GMEM_MOVEABLE, 256);
165
167 mem = GlobalLock(gbl); /* #1 */
168 ok(mem != NULL, "returned %p with %d (expected '!= NULL')\n", mem, GetLastError());
170 flags = GlobalFlags(gbl);
171 ok( flags == 1, "returned 0x%04x with %d (expected '0x0001')\n",
173
175 msecond = GlobalLock(gbl); /* #2 */
176 ok( msecond == mem, "returned %p with %d (expected '%p')\n",
177 msecond, GetLastError(), mem);
179 flags = GlobalFlags(gbl);
180 ok( flags == 2, "returned 0x%04x with %d (expected '0x0002')\n",
183
185 res = GlobalUnlock(gbl); /* #1 */
186 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
188 flags = GlobalFlags(gbl);
189 ok( flags , "returned 0x%04x with %d (expected '!= 0')\n",
191
193 res = GlobalUnlock(gbl); /* #0 */
194 /* NT: ERROR_SUCCESS (documented on MSDN), 9x: untouched */
196 "returned %d with %d (expected '0' with: ERROR_SUCCESS or "
197 "MAGIC_DEAD)\n", res, GetLastError());
199 flags = GlobalFlags(gbl);
200 ok( !flags , "returned 0x%04x with %d (expected '0')\n",
202
203 /* Unlock an already unlocked Handle */
205 res = GlobalUnlock(gbl);
206 /* NT: ERROR_NOT_LOCKED, 9x: untouched */
207 ok( !res &&
209 "returned %d with %d (expected '0' with: ERROR_NOT_LOCKED or "
210 "MAGIC_DEAD)\n", res, GetLastError());
211
212 GlobalFree(gbl);
213 /* invalid handles are caught in windows: */
215 hsecond = GlobalFree(gbl); /* invalid handle: free memory twice */
216 ok( (hsecond == gbl) && (GetLastError() == ERROR_INVALID_HANDLE),
217 "returned %p with 0x%08x (expected %p with ERROR_INVALID_HANDLE)\n",
218 hsecond, GetLastError(), gbl);
220 hsecond = GlobalFree(LongToHandle(0xdeadbeef)); /* bogus handle */
221 ok( (hsecond == LongToHandle(0xdeadbeef)) && (GetLastError() == ERROR_INVALID_HANDLE),
222 "returned %p with 0x%08x (expected %p with ERROR_INVALID_HANDLE)\n",
223 hsecond, GetLastError(), LongToHandle(0xdeadbeef));
225 hsecond = GlobalFree(LongToHandle(0xdeadbee0)); /* bogus pointer */
226 ok( (hsecond == LongToHandle(0xdeadbee0)) &&
228 "returned %p with 0x%08x (expected %p with ERROR_NOACCESS)\n",
229 hsecond, GetLastError(), LongToHandle(0xdeadbee0));
230
232 flags = GlobalFlags(gbl);
234 "returned 0x%04x with 0x%08x (expected GMEM_INVALID_HANDLE with "
235 "ERROR_INVALID_HANDLE)\n", flags, GetLastError());
237 size = GlobalSize(gbl);
238 ok( (size == 0) && (GetLastError() == ERROR_INVALID_HANDLE),
239 "returned %ld with 0x%08x (expected '0' with ERROR_INVALID_HANDLE)\n",
240 size, GetLastError());
241
243 mem = GlobalLock(gbl);
245 "returned %p with 0x%08x (expected NULL with ERROR_INVALID_HANDLE)\n",
246 mem, GetLastError());
247
248 /* documented on MSDN: GlobalUnlock() return FALSE on failure.
249 Win9x and wine return FALSE with ERROR_INVALID_HANDLE, but on
250 NT 3.51 and XPsp2, TRUE with ERROR_INVALID_HANDLE is returned.
251 The similar Test for LocalUnlock() works on all Systems */
253 res = GlobalUnlock(gbl);
255 "returned %d with %d (expected ERROR_INVALID_HANDLE)\n",
256 res, GetLastError());
257
258 gbl = GlobalAlloc(GMEM_DDESHARE, 100);
259
260 /* first free */
261 mem = GlobalFree(gbl);
262 ok(mem == NULL, "Expected NULL, got %p\n", mem);
263
264 /* invalid free */
265 if (sizeof(void *) != 8) /* crashes on 64-bit */
266 {
268 mem = GlobalFree(gbl);
269 ok(mem == gbl || broken(mem == NULL) /* nt4 */, "Expected gbl, got %p\n", mem);
270 if (mem == gbl)
272 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
273 "Expected ERROR_INVALID_HANDLE or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
274 }
275
276 /* GMEM_FIXED block expands in place only without flags */
277 for (size = 1; size <= max_size; size <<= 1) {
278 gbl = GlobalAlloc(GMEM_FIXED, init_size);
280 hsecond = GlobalReAlloc(gbl, size + init_size, 0);
281 ok(hsecond == gbl || (hsecond == NULL && GetLastError() == ERROR_NOT_ENOUGH_MEMORY),
282 "got %p with %x (expected %p or NULL) @%ld\n", hsecond, GetLastError(), gbl, size);
283 GlobalFree(gbl);
284 }
285
286 /* GMEM_FIXED block can be relocated with GMEM_MOVEABLE */
287 for (size = 1; size <= max_size; size <<= 1) {
288 gbl = GlobalAlloc(GMEM_FIXED, init_size);
290 hsecond = GlobalReAlloc(gbl, size + init_size, GMEM_MOVEABLE);
291 ok(hsecond != NULL,
292 "got %p with %x (expected non-NULL) @%ld\n", hsecond, GetLastError(), size);
293 mem = GlobalLock(hsecond);
294 ok(mem == hsecond, "got %p (expected %p) @%ld\n", mem, hsecond, size);
295 GlobalFree(hsecond);
296 }
297
298 gbl = GlobalAlloc(GMEM_DDESHARE, 100);
299
300 res = GlobalUnlock(gbl);
301 ok(res == 1 ||
302 broken(res == 0), /* win9x */
303 "Expected 1 or 0, got %d\n", res);
304
305 res = GlobalUnlock(gbl);
306 ok(res == 1 ||
307 broken(res == 0), /* win9x */
308 "Expected 1 or 0, got %d\n", res);
309
310 GlobalFree(gbl);
311
312 gbl = GlobalAlloc(GMEM_FIXED, 100);
313
314 SetLastError(0xdeadbeef);
315 res = GlobalUnlock(gbl);
316 ok(res == 1 ||
317 broken(res == 0), /* win9x */
318 "Expected 1 or 0, got %d\n", res);
319 ok(GetLastError() == 0xdeadbeef, "got %d\n", GetLastError());
320
321 GlobalFree(gbl);
322
323 /* GlobalSize on an invalid handle */
324 if (sizeof(void *) != 8) /* crashes on 64-bit Vista */
325 {
327 size = GlobalSize((HGLOBAL)0xc042);
328 ok(size == 0, "Expected 0, got %ld\n", size);
330 GetLastError() == ERROR_INVALID_PARAMETER, /* win9x */
331 "Expected ERROR_INVALID_HANDLE or ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
332 }
333
334 gbl = GlobalAlloc( GMEM_FIXED, 0 );
335 SetLastError(0xdeadbeef);
336 size = GlobalSize( gbl );
337 ok( size == 1, "wrong size %lu\n", size );
338 GlobalFree( gbl );
339
340 /* ####################################### */
341 /* Local*() functions */
342 gbl = LocalAlloc(LMEM_MOVEABLE, 0);
343 ok(gbl != NULL, "local memory not allocated for size 0\n");
344
345 gbl = LocalReAlloc(gbl, 10, LMEM_MOVEABLE);
346 ok(gbl != NULL, "Can't realloc local memory\n");
347 size = LocalSize(gbl);
348 ok(size >= 10 && size <= 16, "Memory not resized to size 10, instead size=%ld\n", size);
349
350 gbl = LocalReAlloc(gbl, 0, LMEM_MOVEABLE);
351 ok(gbl != NULL, "LocalReAlloc should not fail on size 0\n");
352
353 size = LocalSize(gbl);
354 ok(size == 0, "Memory not resized to size 0, instead size=%ld\n", size);
355 ok(LocalFree(gbl) == NULL, "Memory not freed\n");
356 size = LocalSize(gbl);
357 ok(size == 0, "Memory should have been freed, size=%ld\n", size);
358
359 gbl = LocalReAlloc(0, 10, LMEM_MOVEABLE);
360 ok(gbl == NULL, "local realloc allocated memory\n");
361
362 /* LocalLock / LocalUnlock with a valid handle */
363 gbl = LocalAlloc(LMEM_MOVEABLE, 256);
365 mem = LocalLock(gbl); /* #1 */
366 ok(mem != NULL, "returned %p with %d (expected '!= NULL')\n", mem, GetLastError());
368 flags = LocalFlags(gbl);
369 ok( flags == 1, "returned 0x%04x with %d (expected '0x0001')\n",
371
373 msecond = LocalLock(gbl); /* #2 */
374 ok( msecond == mem, "returned %p with %d (expected '%p')\n",
375 msecond, GetLastError(), mem);
377 flags = LocalFlags(gbl);
378 ok( flags == 2, "returned 0x%04x with %d (expected '0x0002')\n",
381
383 res = LocalUnlock(gbl); /* #1 */
384 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError());
386 flags = LocalFlags(gbl);
387 ok( flags , "returned 0x%04x with %d (expected '!= 0')\n",
389
391 res = LocalUnlock(gbl); /* #0 */
392 /* NT: ERROR_SUCCESS (documented on MSDN), 9x: untouched */
394 "returned %d with %d (expected '0' with: ERROR_SUCCESS or "
395 "MAGIC_DEAD)\n", res, GetLastError());
397 flags = LocalFlags(gbl);
398 ok( !flags , "returned 0x%04x with %d (expected '0')\n",
400
401 /* Unlock an already unlocked Handle */
403 res = LocalUnlock(gbl);
404 /* NT: ERROR_NOT_LOCKED, 9x: untouched */
405 ok( !res &&
407 "returned %d with %d (expected '0' with: ERROR_NOT_LOCKED or "
408 "MAGIC_DEAD)\n", res, GetLastError());
409
410 LocalFree(gbl);
411 /* invalid handles are caught in windows: */
413 hsecond = LocalFree(gbl); /* invalid handle: free memory twice */
414 ok( (hsecond == gbl) && (GetLastError() == ERROR_INVALID_HANDLE),
415 "returned %p with 0x%08x (expected %p with ERROR_INVALID_HANDLE)\n",
416 hsecond, GetLastError(), gbl);
418 flags = LocalFlags(gbl);
420 "returned 0x%04x with 0x%08x (expected LMEM_INVALID_HANDLE with "
421 "ERROR_INVALID_HANDLE)\n", flags, GetLastError());
423 size = LocalSize(gbl);
424 ok( (size == 0) && (GetLastError() == ERROR_INVALID_HANDLE),
425 "returned %ld with 0x%08x (expected '0' with ERROR_INVALID_HANDLE)\n",
426 size, GetLastError());
427
429 mem = LocalLock(gbl);
431 "returned %p with 0x%08x (expected NULL with ERROR_INVALID_HANDLE)\n",
432 mem, GetLastError());
433
434 /* This Test works the same on all Systems (GlobalUnlock() is different) */
436 res = LocalUnlock(gbl);
438 "returned %d with %d (expected '0' with ERROR_INVALID_HANDLE)\n",
439 res, GetLastError());
440
441 /* LMEM_FIXED block expands in place only without flags */
442 for (size = 1; size <= max_size; size <<= 1) {
443 gbl = LocalAlloc(LMEM_FIXED, init_size);
445 hsecond = LocalReAlloc(gbl, size + init_size, 0);
446 ok(hsecond == gbl || (hsecond == NULL && GetLastError() == ERROR_NOT_ENOUGH_MEMORY),
447 "got %p with %x (expected %p or NULL) @%ld\n", hsecond, GetLastError(), gbl, size);
448 LocalFree(gbl);
449 }
450
451 /* LMEM_FIXED memory can be relocated with LMEM_MOVEABLE */
452 for (size = 1; size <= max_size; size <<= 1) {
453 gbl = LocalAlloc(LMEM_FIXED, init_size);
455 hsecond = LocalReAlloc(gbl, size + init_size, LMEM_MOVEABLE);
456 ok(hsecond != NULL,
457 "got %p with %x (expected non-NULL) @%ld\n", hsecond, GetLastError(), size);
458 mem = LocalLock(hsecond);
459 ok(mem == hsecond, "got %p (expected %p) @%ld\n", mem, hsecond, size);
460 LocalFree(hsecond);
461 }
462
463 /* trying to unlock pointer from LocalAlloc */
464 gbl = LocalAlloc(LMEM_FIXED, 100);
465 SetLastError(0xdeadbeef);
466 res = LocalUnlock(gbl);
467 ok(res == 0, "Expected 0, got %d\n", res);
469 broken(GetLastError() == 0xdeadbeef) /* win9x */, "got %d\n", GetLastError());
470 LocalFree(gbl);
471
472 gbl = LocalAlloc( LMEM_FIXED, 0 );
473 SetLastError(0xdeadbeef);
474 size = LocalSize( gbl );
475 ok( !size || broken(size == 1), /* vistau64 */
476 "wrong size %lu\n", size );
477 LocalFree( gbl );
478
479 /* trying to lock empty memory should give an error */
481 ok(gbl != NULL, "returned NULL\n");
483 mem = GlobalLock(gbl);
484 /* NT: ERROR_DISCARDED, 9x: untouched */
485 ok( (mem == NULL) &&
487 "returned %p with 0x%x/%d (expected 'NULL' with: ERROR_DISCARDED or "
488 "MAGIC_DEAD)\n", mem, GetLastError(), GetLastError());
489
490 GlobalFree(gbl);
491
492 /* trying to get size from data pointer (GMEM_MOVEABLE) */
493 gbl = GlobalAlloc(GMEM_MOVEABLE, 0x123);
494 ok(gbl != NULL, "returned NULL\n");
495 mem = GlobalLock(gbl);
496 ok(mem != NULL, "returned NULL.\n");
497 ok(gbl != mem, "unexpectedly equal.\n");
498
499 size = GlobalSize(gbl);
500 size2 = GlobalSize(mem);
501 ok(size == 0x123, "got %lu\n", size);
502 ok(size2 == 0x123, "got %lu\n", size2);
503
504 GlobalFree(gbl);
505
506 /* trying to get size from data pointer (GMEM_FIXED) */
507 gbl = GlobalAlloc(GMEM_FIXED, 0x123);
508 ok(gbl != NULL, "returned NULL\n");
509 mem = GlobalLock(gbl);
510 ok(mem != NULL, "returned NULL.\n");
511 ok(gbl == mem, "got %p, %p.\n", gbl, mem);
512
513 size = GlobalSize(gbl);
514 ok(size == 0x123, "got %lu\n", size);
515
516 GlobalFree(gbl);
517
518 size = GlobalSize((void *)0xdeadbee0);
519 ok(size == 0, "got %lu\n", size);
520
521}
#define broken(x)
Definition: atltest.h:178
static INT max_size
Definition: history.c:51
#define LongToHandle(h)
Definition: basetsd.h:82
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_SUCCESS
Definition: deptool.c:10
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define HeapFree(x, y, z)
Definition: compat.h:735
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
GLuint res
Definition: glext.h:9613
UINT NTAPI GlobalFlags(HGLOBAL hMem)
Definition: heapmem.c:520
HLOCAL NTAPI LocalReAlloc(HLOCAL hMem, SIZE_T dwBytes, UINT uFlags)
Definition: heapmem.c:1625
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1390
LPVOID NTAPI LocalLock(HLOCAL hMem)
Definition: heapmem.c:1616
BOOL NTAPI LocalUnlock(HLOCAL hMem)
Definition: heapmem.c:1805
SIZE_T NTAPI LocalSize(HLOCAL hMem)
Definition: heapmem.c:1794
UINT NTAPI LocalFlags(HLOCAL hMem)
Definition: heapmem.c:1520
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
static SIZE_T resize_9x(SIZE_T size)
Definition: heap.c:53
static SIZE_T
Definition: heap.c:41
#define MAGIC_DEAD
Definition: heap.c:33
#define DWORD
Definition: nt_native.h:44
#define LPVOID
Definition: nt_native.h:45
Definition: mem.c:349
PVOID HANDLE
Definition: typedefs.h:73
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define LMEM_MOVEABLE
Definition: winbase.h:395
SIZE_T WINAPI HeapSize(HANDLE, DWORD, LPCVOID)
#define GMEM_INVALID_HANDLE
Definition: winbase.h:334
#define GMEM_FIXED
Definition: winbase.h:319
#define LMEM_INVALID_HANDLE
Definition: winbase.h:404
#define GMEM_DDESHARE
Definition: winbase.h:324
#define LMEM_FIXED
Definition: winbase.h:394
#define WINAPI
Definition: msvc.h:6
#define ERROR_DISCARDED
Definition: winerror.h:229
#define ERROR_NOT_LOCKED
Definition: winerror.h:230
#define ERROR_NOACCESS
Definition: winerror.h:578

Referenced by START_TEST().

◆ test_heap_checks()

static void test_heap_checks ( DWORD  flags)
static

Definition at line 895 of file heap.c.

896{
897 BYTE old, *p, *p2;
898 BOOL ret;
899 SIZE_T i, size, large_size = 3000 * 1024 + 37;
900
901 if (flags & HEAP_PAGE_ALLOCS) return; /* no tests for that case yet */
902 trace( "testing heap flags %08x\n", flags );
903
905 ok( p != NULL, "HeapAlloc failed\n" );
906
907 ret = HeapValidate( GetProcessHeap(), 0, p );
908 ok( ret, "HeapValidate failed\n" );
909
910 size = HeapSize( GetProcessHeap(), 0, p );
911 ok( size == 17, "Wrong size %lu\n", size );
912
913 ok( p[14] == 0, "wrong data %x\n", p[14] );
914 ok( p[15] == 0, "wrong data %x\n", p[15] );
915 ok( p[16] == 0, "wrong data %x\n", p[16] );
916
918 {
919 ok( p[17] == 0xab, "wrong padding %x\n", p[17] );
920 ok( p[18] == 0xab, "wrong padding %x\n", p[18] );
921 ok( p[19] == 0xab, "wrong padding %x\n", p[19] );
922 }
923
925 if (p2 == p)
926 {
928 {
929 ok( p[14] == 0xab, "wrong padding %x\n", p[14] );
930 ok( p[15] == 0xab, "wrong padding %x\n", p[15] );
931 ok( p[16] == 0xab, "wrong padding %x\n", p[16] );
932 }
933 else
934 {
935 ok( p[14] == 0, "wrong padding %x\n", p[14] );
936 ok( p[15] == 0, "wrong padding %x\n", p[15] );
937 }
938 }
939 else skip( "realloc in place failed\n");
940
941 ret = HeapFree( GetProcessHeap(), 0, p );
942 ok( ret, "HeapFree failed\n" );
943
945 ok( p != NULL, "HeapAlloc failed\n" );
946 old = p[17];
947 p[17] = 0xcc;
948
950 {
951 ret = HeapValidate( GetProcessHeap(), 0, p );
952 ok( !ret, "HeapValidate succeeded\n" );
953
954 /* other calls only check when HEAP_VALIDATE is set */
955 if (flags & HEAP_VALIDATE)
956 {
957 size = HeapSize( GetProcessHeap(), 0, p );
958 ok( size == ~(SIZE_T)0 || broken(size == ~0u), "Wrong size %lu\n", size );
959
960 p2 = HeapReAlloc( GetProcessHeap(), 0, p, 14 );
961 ok( p2 == NULL, "HeapReAlloc succeeded\n" );
962
963 ret = HeapFree( GetProcessHeap(), 0, p );
964 ok( !ret || broken(sizeof(void*) == 8), /* not caught on xp64 */
965 "HeapFree succeeded\n" );
966 }
967
968 p[17] = old;
969 size = HeapSize( GetProcessHeap(), 0, p );
970 ok( size == 17, "Wrong size %lu\n", size );
971
972 p2 = HeapReAlloc( GetProcessHeap(), 0, p, 14 );
973 ok( p2 != NULL, "HeapReAlloc failed\n" );
974 p = p2;
975 }
976
977 ret = HeapFree( GetProcessHeap(), 0, p );
978 ok( ret, "HeapFree failed\n" );
979
980 p = HeapAlloc( GetProcessHeap(), 0, 37 );
981 ok( p != NULL, "HeapAlloc failed\n" );
982 memset( p, 0xcc, 37 );
983
984 ret = HeapFree( GetProcessHeap(), 0, p );
985 ok( ret, "HeapFree failed\n" );
986
988 {
989 ok( p[16] == 0xee, "wrong data %x\n", p[16] );
990 ok( p[17] == 0xfe, "wrong data %x\n", p[17] );
991 ok( p[18] == 0xee, "wrong data %x\n", p[18] );
992 ok( p[19] == 0xfe, "wrong data %x\n", p[19] );
993
995 ok( ret, "HeapValidate failed\n" );
996
997 old = p[16];
998 p[16] = 0xcc;
1000 ok( !ret, "HeapValidate succeeded\n" );
1001
1002 p[16] = old;
1004 ok( ret, "HeapValidate failed\n" );
1005 }
1006
1007 /* now test large blocks */
1008
1009 p = HeapAlloc( GetProcessHeap(), 0, large_size );
1010 ok( p != NULL, "HeapAlloc failed\n" );
1011
1012 ret = HeapValidate( GetProcessHeap(), 0, p );
1013 ok( ret, "HeapValidate failed\n" );
1014
1015 size = HeapSize( GetProcessHeap(), 0, p );
1016 ok( size == large_size, "Wrong size %lu\n", size );
1017
1018 ok( p[large_size - 2] == 0, "wrong data %x\n", p[large_size - 2] );
1019 ok( p[large_size - 1] == 0, "wrong data %x\n", p[large_size - 1] );
1020
1022 {
1023 /* Windows doesn't do tail checking on large blocks */
1024 ok( p[large_size] == 0xab || broken(p[large_size] == 0), "wrong data %x\n", p[large_size] );
1025 ok( p[large_size+1] == 0xab || broken(p[large_size+1] == 0), "wrong data %x\n", p[large_size+1] );
1026 ok( p[large_size+2] == 0xab || broken(p[large_size+2] == 0), "wrong data %x\n", p[large_size+2] );
1027 if (p[large_size] == 0xab)
1028 {
1029 p[large_size] = 0xcc;
1030 ret = HeapValidate( GetProcessHeap(), 0, p );
1031 ok( !ret, "HeapValidate succeeded\n" );
1032
1033 /* other calls only check when HEAP_VALIDATE is set */
1034 if (flags & HEAP_VALIDATE)
1035 {
1036 size = HeapSize( GetProcessHeap(), 0, p );
1037 ok( size == ~(SIZE_T)0, "Wrong size %lu\n", size );
1038
1039 p2 = HeapReAlloc( GetProcessHeap(), 0, p, large_size - 3 );
1040 ok( p2 == NULL, "HeapReAlloc succeeded\n" );
1041
1042 ret = HeapFree( GetProcessHeap(), 0, p );
1043 ok( !ret, "HeapFree succeeded\n" );
1044 }
1045 p[large_size] = 0xab;
1046 }
1047 }
1048
1049 ret = HeapFree( GetProcessHeap(), 0, p );
1050 ok( ret, "HeapFree failed\n" );
1051
1052 /* test block sizes when tail checking */
1054 {
1055 for (size = 0; size < 64; size++)
1056 {
1057 p = HeapAlloc( GetProcessHeap(), 0, size );
1058 for (i = 0; i < 32; i++) if (p[size + i] != 0xab) break;
1059 ok( i >= 8, "only %lu tail bytes for size %lu\n", i, size );
1060 HeapFree( GetProcessHeap(), 0, p );
1061 }
1062 }
1063}
#define trace
Definition: atltest.h:70
GLfloat GLfloat p
Definition: glext.h:8902
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
BOOL WINAPI HeapValidate(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem)
Definition: heapmem.c:156
#define HEAP_REALLOC_IN_PLACE_ONLY
Definition: nt_native.h:1696

Referenced by test_child_heap().

◆ test_HeapCreate()

static void test_HeapCreate ( void  )
static

Definition at line 524 of file heap.c.

525{
526 SYSTEM_INFO sysInfo;
527 ULONG memchunk;
528 HANDLE heap;
529 LPVOID mem1,mem1a,mem3;
530 UCHAR *mem2,*mem2a;
531 UINT i;
532 BOOL error;
534
535 /* Retrieve the page size for this system */
536 GetSystemInfo(&sysInfo);
537 ok(sysInfo.dwPageSize>0,"GetSystemInfo should return a valid page size\n");
538
539 /* Create a Heap with a minimum and maximum size */
540 /* Note that Windows and Wine seem to behave a bit differently with respect
541 to memory allocation. In Windows, you can't access all the memory
542 specified in the heap (due to overhead), so choosing a reasonable maximum
543 size for the heap was done mostly by trial-and-error on Win2k. It may need
544 more tweaking for otherWindows variants.
545 */
546 memchunk=10*sysInfo.dwPageSize;
547 heap=HeapCreate(0,2*memchunk,5*memchunk);
548 ok( !((ULONG_PTR)heap & 0xffff), "heap %p not 64K aligned\n", heap );
549
550 /* Check that HeapCreate allocated the right amount of ram */
551 mem1=HeapAlloc(heap,0,5*memchunk+1);
552 ok(mem1==NULL,"HeapCreate allocated more Ram than it should have\n");
553 HeapFree(heap,0,mem1);
554
555 /* Check that a normal alloc works */
556 mem1=HeapAlloc(heap,0,memchunk);
557 ok(mem1!=NULL,"HeapAlloc failed\n");
558 if(mem1) {
559 ok(HeapSize(heap,0,mem1)>=memchunk, "HeapAlloc should return a big enough memory block\n");
560 }
561
562 /* Check that a 'zeroing' alloc works */
563 mem2=HeapAlloc(heap,HEAP_ZERO_MEMORY,memchunk);
564 ok(mem2!=NULL,"HeapAlloc failed\n");
565 if(mem2) {
566 ok(HeapSize(heap,0,mem2)>=memchunk,"HeapAlloc should return a big enough memory block\n");
567 error=FALSE;
568 for(i=0;i<memchunk;i++) {
569 if(mem2[i]!=0) {
570 error=TRUE;
571 }
572 }
573 ok(!error,"HeapAlloc should have zeroed out its allocated memory\n");
574 }
575
576 /* Check that HeapAlloc returns NULL when requested way too much memory */
577 mem3=HeapAlloc(heap,0,5*memchunk);
578 ok(mem3==NULL,"HeapAlloc should return NULL\n");
579 if(mem3) {
580 ok(HeapFree(heap,0,mem3),"HeapFree didn't pass successfully\n");
581 }
582
583 /* Check that HeapReAlloc works */
584 mem2a=HeapReAlloc(heap,HEAP_ZERO_MEMORY,mem2,memchunk+5*sysInfo.dwPageSize);
585 ok(mem2a!=NULL,"HeapReAlloc failed\n");
586 if(mem2a) {
587 ok(HeapSize(heap,0,mem2a)>=memchunk+5*sysInfo.dwPageSize,"HeapReAlloc failed\n");
588 error=FALSE;
589 for(i=0;i<5*sysInfo.dwPageSize;i++) {
590 if(mem2a[memchunk+i]!=0) {
591 error=TRUE;
592 }
593 }
594 ok(!error,"HeapReAlloc should have zeroed out its allocated memory\n");
595 }
596
597 /* Check that HeapReAlloc honours HEAP_REALLOC_IN_PLACE_ONLY */
598 error=FALSE;
599 mem1a=HeapReAlloc(heap,HEAP_REALLOC_IN_PLACE_ONLY,mem1,memchunk+sysInfo.dwPageSize);
600 if(mem1a!=NULL) {
601 if(mem1a!=mem1) {
602 error=TRUE;
603 }
604 }
605 ok(mem1a==NULL || !error,"HeapReAlloc didn't honour HEAP_REALLOC_IN_PLACE_ONLY\n");
606
607 /* Check that HeapFree works correctly */
608 if(mem1a) {
609 ok(HeapFree(heap,0,mem1a),"HeapFree failed\n");
610 } else {
611 ok(HeapFree(heap,0,mem1),"HeapFree failed\n");
612 }
613 if(mem2a) {
614 ok(HeapFree(heap,0,mem2a),"HeapFree failed\n");
615 } else {
616 ok(HeapFree(heap,0,mem2),"HeapFree failed\n");
617 }
618
619 /* 0-length buffer */
620 mem1 = HeapAlloc(heap, 0, 0);
621 ok(mem1 != NULL, "Reserved memory\n");
622
623 dwSize = HeapSize(heap, 0, mem1);
624 /* should work with 0-length buffer */
625 ok(dwSize < 0xFFFFFFFF, "The size of the 0-length buffer\n");
626 ok(HeapFree(heap, 0, mem1), "Freed the 0-length buffer\n");
627
628 /* Check that HeapDestroy works */
629 ok(HeapDestroy(heap),"HeapDestroy failed\n");
630}
VOID WINAPI GetSystemInfo(IN LPSYSTEM_INFO lpSystemInfo)
Definition: sysinfo.c:143
HANDLE WINAPI HeapCreate(DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaximumSize)
Definition: heapmem.c:45
BOOL WINAPI HeapDestroy(HANDLE hHeap)
Definition: heapmem.c:85
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:56
DWORD dwPageSize
Definition: winbase.h:1198

Referenced by START_TEST().

◆ test_HeapQueryInformation()

static void test_HeapQueryInformation ( void  )
static

Definition at line 843 of file heap.c.

844{
845 ULONG info;
846 SIZE_T size;
847 BOOL ret;
848
849 pHeapQueryInformation = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "HeapQueryInformation");
850 if (!pHeapQueryInformation)
851 {
852 win_skip("HeapQueryInformation is not available\n");
853 return;
854 }
855
856 if (0) /* crashes under XP */
857 {
858 size = 0;
859 pHeapQueryInformation(0,
861 &info, sizeof(info), &size);
862 size = 0;
863 pHeapQueryInformation(GetProcessHeap(),
865 NULL, sizeof(info), &size);
866 }
867
868 size = 0;
869 SetLastError(0xdeadbeef);
870 ret = pHeapQueryInformation(GetProcessHeap(),
872 NULL, 0, &size);
873 ok(!ret, "HeapQueryInformation should fail\n");
875 "expected ERROR_INSUFFICIENT_BUFFER got %u\n", GetLastError());
876 ok(size == sizeof(ULONG), "expected 4, got %lu\n", size);
877
878 SetLastError(0xdeadbeef);
879 ret = pHeapQueryInformation(GetProcessHeap(),
881 NULL, 0, NULL);
882 ok(!ret, "HeapQueryInformation should fail\n");
884 "expected ERROR_INSUFFICIENT_BUFFER got %u\n", GetLastError());
885
886 info = 0xdeadbeaf;
887 SetLastError(0xdeadbeef);
888 ret = pHeapQueryInformation(GetProcessHeap(),
890 &info, sizeof(info) + 1, NULL);
891 ok(ret, "HeapQueryInformation error %u\n", GetLastError());
892 ok(info == 0 || info == 1 || info == 2, "expected 0, 1 or 2, got %u\n", info);
893}
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
@ HeapCompatibilityInformation
Definition: rtltypes.h:488

Referenced by START_TEST().

◆ test_LocalAlloc()

static void test_LocalAlloc ( void  )
static

Definition at line 715 of file heap.c.

716{
717 ULONG memchunk;
718 HLOCAL mem1,mem2,mem2a,mem2b;
719 UCHAR *mem2ptr;
720 UINT i;
721 BOOL error;
722 memchunk=100000;
723
724 /* Check that a normal alloc works */
725 mem1=LocalAlloc(0,memchunk);
726 ok(mem1!=NULL,"LocalAlloc failed: error=%d\n",GetLastError());
727 if(mem1) {
728 ok(LocalSize(mem1)>=memchunk, "LocalAlloc should return a big enough memory block\n");
729 }
730
731 /* Check that a 'zeroing' and lock alloc works */
733 ok(mem2!=NULL,"LocalAlloc failed: error=%d\n",GetLastError());
734 if(mem2) {
735 ok(LocalSize(mem2)>=memchunk,"LocalAlloc should return a big enough memory block\n");
736 mem2ptr=LocalLock(mem2);
737 ok(mem2ptr!=NULL,"LocalLock: error=%d\n",GetLastError());
738 if(mem2ptr) {
739 error=FALSE;
740 for(i=0;i<memchunk;i++) {
741 if(mem2ptr[i]!=0) {
742 error=TRUE;
743 }
744 }
745 ok(!error,"LocalAlloc should have zeroed out its allocated memory\n");
746 SetLastError(0);
747 error=LocalUnlock(mem2);
749 "LocalUnlock Failed: rc=%d err=%d\n",error,GetLastError());
750 }
751 }
752 mem2a=LocalFree(mem2);
753 ok(mem2a==NULL, "LocalFree failed: %p\n",mem2a);
754
755 /* Reallocate mem2 as moveable memory */
756 mem2=LocalAlloc(LMEM_MOVEABLE | LMEM_ZEROINIT,memchunk);
757 ok(mem2!=NULL, "LocalAlloc failed to create moveable memory, error=%d\n",GetLastError());
758
759 /* Check that ReAllocing memory works as expected */
760 mem2a=LocalReAlloc(mem2,2*memchunk,LMEM_MOVEABLE | LMEM_ZEROINIT);
761 ok(mem2a!=NULL,"LocalReAlloc failed, error=%d\n",GetLastError());
762 if(mem2a) {
763 ok(LocalSize(mem2a)>=2*memchunk,"LocalReAlloc failed\n");
764 mem2ptr=LocalLock(mem2a);
765 ok(mem2ptr!=NULL,"LocalLock Failed\n");
766 if(mem2ptr) {
767 error=FALSE;
768 for(i=0;i<memchunk;i++) {
769 if(mem2ptr[memchunk+i]!=0) {
770 error=TRUE;
771 }
772 }
773 ok(!error,"LocalReAlloc should have zeroed out its allocated memory\n");
774 /* Check that LocalHandle works */
775 mem2b=LocalHandle(mem2ptr);
776 ok(mem2b==mem2a,"LocalHandle didn't return the correct memory handle %p/%p for %p\n",
777 mem2a, mem2b, mem2ptr);
778 /* Check that we can't discard locked memory */
779 mem2b=LocalDiscard(mem2a);
780 ok(mem2b==NULL,"Discarded memory we shouldn't have\n");
782 ok(!LocalUnlock(mem2a) && GetLastError()==NO_ERROR, "LocalUnlock Failed\n");
783 }
784 }
785 if(mem1) {
786 ok(LocalFree(mem1)==NULL,"LocalFree failed\n");
787 }
788 if(mem2a) {
789 ok(LocalFree(mem2a)==NULL,"LocalFree failed\n");
790 } else {
791 ok(LocalFree(mem2)==NULL,"LocalFree failed\n");
792 }
793}
HLOCAL NTAPI LocalHandle(LPCVOID pMem)
Definition: heapmem.c:1605
#define LocalDiscard(m)
Definition: winbase.h:2714
#define LMEM_ZEROINIT
Definition: winbase.h:401

Referenced by START_TEST().

◆ test_obsolete_flags()

static void test_obsolete_flags ( void  )
static

Definition at line 795 of file heap.c.

796{
797 static struct {
798 UINT flags;
799 UINT globalflags;
800 } test_global_flags[] = {
801 {GMEM_FIXED | GMEM_NOTIFY, 0},
810 };
811
812 unsigned int i;
813 HGLOBAL gbl;
814 UINT resultflags;
815
816 UINT (WINAPI *pGlobalFlags)(HGLOBAL);
817
818 pGlobalFlags = (void *) GetProcAddress(GetModuleHandleA("kernel32"), "GlobalFlags");
819
820 if (!pGlobalFlags)
821 {
822 win_skip("GlobalFlags is not available\n");
823 return;
824 }
825
826 for (i = 0; i < sizeof(test_global_flags)/sizeof(test_global_flags[0]); i++)
827 {
828 gbl = GlobalAlloc(test_global_flags[i].flags, 4);
829 ok(gbl != NULL, "GlobalAlloc failed\n");
830
832 resultflags = pGlobalFlags(gbl);
833
834 ok( resultflags == test_global_flags[i].globalflags ||
835 broken(resultflags == (test_global_flags[i].globalflags & ~GMEM_DDESHARE)), /* win9x */
836 "%u: expected 0x%08x, but returned 0x%08x with %d\n",
837 i, test_global_flags[i].globalflags, resultflags, GetLastError() );
838
839 GlobalFree(gbl);
840 }
841}
#define HGLOBAL
Definition: ole.h:15
#define GMEM_DISCARDABLE
Definition: winbase.h:325
#define GMEM_LOWER
Definition: winbase.h:326
#define GMEM_NOCOMPACT
Definition: winbase.h:327
#define GMEM_NODISCARD
Definition: winbase.h:328
#define GMEM_NOT_BANKED
Definition: winbase.h:329
#define GMEM_NOTIFY
Definition: winbase.h:330

Referenced by START_TEST().

◆ test_sized_HeapAlloc()

static void test_sized_HeapAlloc ( int  nbytes)
static

Definition at line 59 of file heap.c.

60{
62 char *buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nbytes);
63 ok(buf != NULL, "allocate failed\n");
64 ok(buf[0] == 0, "buffer not zeroed\n");
66 ok(success, "free failed\n");
67}
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define success(from, fromstr, to, tostr)

Referenced by START_TEST().

◆ test_sized_HeapReAlloc()

static void test_sized_HeapReAlloc ( int  nbytes1,
int  nbytes2 
)
static

Definition at line 69 of file heap.c.

70{
72 char *buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nbytes1);
73 ok(buf != NULL, "allocate failed\n");
74 ok(buf[0] == 0, "buffer not zeroed\n");
76 ok(buf != NULL, "reallocate failed\n");
77 ok(buf[nbytes2-1] == 0, "buffer not zeroed\n");
79 ok(success, "free failed\n");
80}

Referenced by START_TEST().

◆ ULONG()

static ULONG ( WINAPI pRtlGetNtGlobalFlags)
static

Variable Documentation

◆ HEAP_INFORMATION_CLASS

Definition at line 41 of file heap.c.

◆ PSIZE_T

Definition at line 41 of file heap.c.

◆ PVOID

◆ SIZE_T

Definition at line 41 of file heap.c.

Referenced by test_heap().