Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
4ef64132
Commit
4ef64132
authored
Jan 23, 2000
by
Guy Albertelli
Committed by
Alexandre Julliard
Jan 23, 2000
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix problems with GlobalHandle and GlobalFree so results match Win98.
Restructure HEAP_ValidateInUseArena, HeapValidate, and add HEAP_IsRealArena to eliminate *bogus* error messages.
parent
8be3bf1c
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
132 additions
and
76 deletions
+132
-76
global.c
memory/global.c
+26
-11
heap.c
memory/heap.c
+106
-65
No files found.
memory/global.c
View file @
4ef64132
...
...
@@ -1142,26 +1142,37 @@ HGLOBAL WINAPI GlobalHandle(
)
{
HGLOBAL
handle
;
HANDLE
heap
;
PGLOBAL32_INTERN
maybe_intern
;
LPCVOID
test
;
if
(
!
pmem
)
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
0
;
}
heap
=
GLOBAL_GetHeap
(
POINTER_TO_HANDLE
(
pmem
)
);
if
(
!
HEAP_IsInsideHeap
(
heap
,
0
,
pmem
))
goto
error
;
/* note that if pmem is a pointer to a a block allocated by */
/* GlobalAlloc with GMEM_MOVEABLE then magic test in HeapValidate */
/* will fail. */
if
(
ISPOINTER
(
pmem
))
{
heap
=
GLOBAL_GetHeap
(
(
HGLOBAL
)
pmem
);
if
(
HeapValidate
(
heap
,
0
,
pmem
))
return
(
HGLOBAL
)
pmem
;
/* valid fixed block */
handle
=
POINTER_TO_HANDLE
(
pmem
);
if
(
HEAP_IsInsideHeap
(
heap
,
0
,
(
LPCVOID
)
handle
))
{
if
(
HANDLE_TO_INTERN
(
handle
)
->
Magic
==
MAGIC_GLOBAL_USED
)
}
else
handle
=
(
HGLOBAL
)
pmem
;
/* Now test handle either passed in or retrieved from pointer */
heap
=
GLOBAL_GetHeap
(
handle
);
maybe_intern
=
HANDLE_TO_INTERN
(
handle
);
if
(
maybe_intern
->
Magic
==
MAGIC_GLOBAL_USED
)
{
test
=
maybe_intern
->
Pointer
;
if
(
HeapValidate
(
heap
,
0
,
((
HGLOBAL
*
)
test
)
-
1
)
&&
/* obj(-handle) valid arena? */
HeapValidate
(
heap
,
0
,
maybe_intern
))
/* intern valid arena? */
return
handle
;
/* valid moveable block */
}
/* maybe FIXED block */
if
(
HeapValidate
(
heap
,
0
,
pmem
))
return
(
HGLOBAL
)
pmem
;
/* valid fixed block */
error:
SetLastError
(
ERROR_INVALID_HANDLE
);
return
0
;
}
...
...
@@ -1289,8 +1300,12 @@ HGLOBAL WINAPI GlobalFree(
if
(
pintern
->
Magic
==
MAGIC_GLOBAL_USED
)
{
if
(
pintern
->
LockCount
!=
0
)
SetLastError
(
ERROR_INVALID_HANDLE
);
/* WIN98 does not make this test. That is you can free a */
/* block you have not unlocked. Go figure!! */
/* if(pintern->LockCount!=0) */
/* SetLastError(ERROR_INVALID_HANDLE); */
if
(
pintern
->
Pointer
)
if
(
!
HeapFree
(
heap
,
0
,
(
char
*
)(
pintern
->
Pointer
)
-
sizeof
(
HGLOBAL
)))
...
...
memory/heap.c
View file @
4ef64132
...
...
@@ -53,6 +53,9 @@ typedef struct tagARENA_FREE
#define ARENA_INUSE_FILLER 0x55
#define ARENA_FREE_FILLER 0xaa
#define QUIET 1
/* Suppress messages */
#define NOISY 0
/* Report all errors */
#define HEAP_NB_FREE_LISTS 4
/* Number of free lists */
/* Max size of the blocks on the free lists */
...
...
@@ -100,6 +103,7 @@ typedef struct tagHEAP
HANDLE
SystemHeap
=
0
;
HANDLE
SegptrHeap
=
0
;
static
BOOL
HEAP_IsRealArena
(
HANDLE
heap
,
DWORD
flags
,
LPCVOID
block
,
BOOL
quiet
);
#ifdef __GNUC__
#define GET_EIP() (__builtin_return_address(0))
...
...
@@ -204,7 +208,7 @@ static HEAP *HEAP_GetPtr(
SetLastError
(
ERROR_INVALID_HANDLE
);
return
NULL
;
}
if
(
TRACE_ON
(
heap
)
&&
!
H
eapValidate
(
heap
,
0
,
NULL
))
if
(
TRACE_ON
(
heap
)
&&
!
H
EAP_IsRealArena
(
heap
,
0
,
NULL
,
NOISY
))
{
HEAP_Dump
(
heapPtr
);
assert
(
FALSE
);
...
...
@@ -737,15 +741,24 @@ static BOOL HEAP_ValidateFreeArena( SUBHEAP *subheap, ARENA_FREE *pArena )
/***********************************************************************
* HEAP_ValidateInUseArena
*/
static
BOOL
HEAP_ValidateInUseArena
(
SUBHEAP
*
subheap
,
ARENA_INUSE
*
pArena
)
static
BOOL
HEAP_ValidateInUseArena
(
SUBHEAP
*
subheap
,
ARENA_INUSE
*
pArena
,
BOOL
quiet
)
{
char
*
heapEnd
=
(
char
*
)
subheap
+
subheap
->
size
;
/* Check magic number */
if
(
pArena
->
magic
!=
ARENA_INUSE_MAGIC
)
{
if
(
quiet
==
NOISY
)
{
ERR
(
"Heap %08lx: invalid in-use arena magic for %08lx
\n
"
,
(
DWORD
)
subheap
->
heap
,
(
DWORD
)
pArena
);
if
(
TRACE_ON
(
heap
))
HEAP_Dump
(
subheap
->
heap
);
}
else
if
(
WARN_ON
(
heap
))
{
WARN
(
"Heap %08lx: invalid in-use arena magic for %08lx
\n
"
,
(
DWORD
)
subheap
->
heap
,
(
DWORD
)
pArena
);
if
(
TRACE_ON
(
heap
))
HEAP_Dump
(
subheap
->
heap
);
}
return
FALSE
;
}
/* Check size flags */
...
...
@@ -874,6 +887,93 @@ SEGPTR HEAP_GetSegptr( HANDLE heap, DWORD flags, LPCVOID ptr )
return
ret
;
}
/***********************************************************************
* HEAP_IsRealArena [Internal]
* Validates a block is a valid arena.
*
* RETURNS
* TRUE: Success
* FALSE: Failure
*/
static
BOOL
HEAP_IsRealArena
(
HANDLE
heap
,
/* [in] Handle to the heap */
DWORD
flags
,
/* [in] Bit flags that control access during operation */
LPCVOID
block
,
/* [in] Optional pointer to memory block to validate */
BOOL
quiet
/* [in] Flag - if true, HEAP_ValidateInUseArena
* does not complain */
)
{
SUBHEAP
*
subheap
;
HEAP
*
heapPtr
=
(
HEAP
*
)(
heap
);
BOOL
ret
=
TRUE
;
if
(
!
heapPtr
||
(
heapPtr
->
magic
!=
HEAP_MAGIC
))
{
ERR
(
"Invalid heap %08x!
\n
"
,
heap
);
return
FALSE
;
}
flags
&=
HEAP_NO_SERIALIZE
;
flags
|=
heapPtr
->
flags
;
/* calling HeapLock may result in infinite recursion, so do the critsect directly */
if
(
!
(
flags
&
HEAP_NO_SERIALIZE
))
EnterCriticalSection
(
&
heapPtr
->
critSection
);
if
(
block
)
{
/* Only check this single memory block */
/* The following code is really HEAP_IsInsideHeap *
* with serialization already done. */
if
(
!
(
subheap
=
HEAP_FindSubHeap
(
heapPtr
,
block
))
||
((
char
*
)
block
<
(
char
*
)
subheap
+
subheap
->
headerSize
+
sizeof
(
ARENA_INUSE
)))
{
if
(
quiet
==
NOISY
)
ERR
(
"Heap %08lx: block %08lx is not inside heap
\n
"
,
(
DWORD
)
heap
,
(
DWORD
)
block
);
else
if
(
WARN_ON
(
heap
))
WARN
(
"Heap %08lx: block %08lx is not inside heap
\n
"
,
(
DWORD
)
heap
,
(
DWORD
)
block
);
ret
=
FALSE
;
}
else
ret
=
HEAP_ValidateInUseArena
(
subheap
,
(
ARENA_INUSE
*
)
block
-
1
,
quiet
);
if
(
!
(
flags
&
HEAP_NO_SERIALIZE
))
LeaveCriticalSection
(
&
heapPtr
->
critSection
);
return
ret
;
}
subheap
=
&
heapPtr
->
subheap
;
while
(
subheap
&&
ret
)
{
char
*
ptr
=
(
char
*
)
subheap
+
subheap
->
headerSize
;
while
(
ptr
<
(
char
*
)
subheap
+
subheap
->
size
)
{
if
(
*
(
DWORD
*
)
ptr
&
ARENA_FLAG_FREE
)
{
if
(
!
HEAP_ValidateFreeArena
(
subheap
,
(
ARENA_FREE
*
)
ptr
))
{
ret
=
FALSE
;
break
;
}
ptr
+=
sizeof
(
ARENA_FREE
)
+
(
*
(
DWORD
*
)
ptr
&
ARENA_SIZE_MASK
);
}
else
{
if
(
!
HEAP_ValidateInUseArena
(
subheap
,
(
ARENA_INUSE
*
)
ptr
,
NOISY
))
{
ret
=
FALSE
;
break
;
}
ptr
+=
sizeof
(
ARENA_INUSE
)
+
(
*
(
DWORD
*
)
ptr
&
ARENA_SIZE_MASK
);
}
}
subheap
=
subheap
->
next
;
}
if
(
!
(
flags
&
HEAP_NO_SERIALIZE
))
LeaveCriticalSection
(
&
heapPtr
->
critSection
);
return
ret
;
}
/***********************************************************************
* HeapCreate (KERNEL32.336)
...
...
@@ -1023,7 +1123,7 @@ BOOL WINAPI HeapFree(
WARN
(
"(%08x,%08lx,%08lx): asked to free NULL
\n
"
,
heap
,
flags
,
(
DWORD
)
ptr
);
}
if
(
!
ptr
||
!
H
eapValidate
(
heap
,
HEAP_NO_SERIALIZE
,
ptr
))
if
(
!
ptr
||
!
H
EAP_IsRealArena
(
heap
,
HEAP_NO_SERIALIZE
,
ptr
,
QUIET
))
{
if
(
!
(
flags
&
HEAP_NO_SERIALIZE
))
HeapUnlock
(
heap
);
SetLastError
(
ERROR_INVALID_PARAMETER
);
...
...
@@ -1076,7 +1176,7 @@ LPVOID WINAPI HeapReAlloc(
if
(
size
<
HEAP_MIN_BLOCK_SIZE
)
size
=
HEAP_MIN_BLOCK_SIZE
;
if
(
!
(
flags
&
HEAP_NO_SERIALIZE
))
HeapLock
(
heap
);
if
(
!
H
eapValidate
(
heap
,
HEAP_NO_SERIALIZE
,
ptr
))
if
(
!
H
EAP_IsRealArena
(
heap
,
HEAP_NO_SERIALIZE
,
ptr
,
QUIET
))
{
if
(
!
(
flags
&
HEAP_NO_SERIALIZE
))
HeapUnlock
(
heap
);
SetLastError
(
ERROR_INVALID_PARAMETER
);
...
...
@@ -1234,7 +1334,7 @@ DWORD WINAPI HeapSize(
flags
&=
HEAP_NO_SERIALIZE
;
flags
|=
heapPtr
->
flags
;
if
(
!
(
flags
&
HEAP_NO_SERIALIZE
))
HeapLock
(
heap
);
if
(
!
H
eapValidate
(
heap
,
HEAP_NO_SERIALIZE
,
ptr
))
if
(
!
H
EAP_IsRealArena
(
heap
,
HEAP_NO_SERIALIZE
,
ptr
,
QUIET
))
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
ret
=
0xffffffff
;
...
...
@@ -1268,67 +1368,8 @@ BOOL WINAPI HeapValidate(
DWORD
flags
,
/* [in] Bit flags that control access during operation */
LPCVOID
block
/* [in] Optional pointer to memory block to validate */
)
{
SUBHEAP
*
subheap
;
HEAP
*
heapPtr
=
(
HEAP
*
)(
heap
);
BOOL
ret
=
TRUE
;
if
(
!
heapPtr
||
(
heapPtr
->
magic
!=
HEAP_MAGIC
))
{
ERR
(
"Invalid heap %08x!
\n
"
,
heap
);
return
FALSE
;
}
flags
&=
HEAP_NO_SERIALIZE
;
flags
|=
heapPtr
->
flags
;
/* calling HeapLock may result in infinite recursion, so do the critsect directly */
if
(
!
(
flags
&
HEAP_NO_SERIALIZE
))
EnterCriticalSection
(
&
heapPtr
->
critSection
);
if
(
block
)
{
/* Only check this single memory block */
if
(
!
(
subheap
=
HEAP_FindSubHeap
(
heapPtr
,
block
))
||
((
char
*
)
block
<
(
char
*
)
subheap
+
subheap
->
headerSize
+
sizeof
(
ARENA_INUSE
)))
{
ERR
(
"Heap %08lx: block %08lx is not inside heap
\n
"
,
(
DWORD
)
heap
,
(
DWORD
)
block
);
ret
=
FALSE
;
}
else
ret
=
HEAP_ValidateInUseArena
(
subheap
,
(
ARENA_INUSE
*
)
block
-
1
);
if
(
!
(
flags
&
HEAP_NO_SERIALIZE
))
LeaveCriticalSection
(
&
heapPtr
->
critSection
);
return
ret
;
}
subheap
=
&
heapPtr
->
subheap
;
while
(
subheap
&&
ret
)
{
char
*
ptr
=
(
char
*
)
subheap
+
subheap
->
headerSize
;
while
(
ptr
<
(
char
*
)
subheap
+
subheap
->
size
)
{
if
(
*
(
DWORD
*
)
ptr
&
ARENA_FLAG_FREE
)
{
if
(
!
HEAP_ValidateFreeArena
(
subheap
,
(
ARENA_FREE
*
)
ptr
))
{
ret
=
FALSE
;
break
;
}
ptr
+=
sizeof
(
ARENA_FREE
)
+
(
*
(
DWORD
*
)
ptr
&
ARENA_SIZE_MASK
);
}
else
{
if
(
!
HEAP_ValidateInUseArena
(
subheap
,
(
ARENA_INUSE
*
)
ptr
))
{
ret
=
FALSE
;
break
;
}
ptr
+=
sizeof
(
ARENA_INUSE
)
+
(
*
(
DWORD
*
)
ptr
&
ARENA_SIZE_MASK
);
}
}
subheap
=
subheap
->
next
;
}
if
(
!
(
flags
&
HEAP_NO_SERIALIZE
))
LeaveCriticalSection
(
&
heapPtr
->
critSection
);
return
ret
;
return
HEAP_IsRealArena
(
heap
,
flags
,
block
,
QUIET
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment