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
54f377c6
Commit
54f377c6
authored
Feb 19, 2003
by
Jukka Heinonen
Committed by
Alexandre Julliard
Feb 19, 2003
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move resize memory block to winedos and make it resize in place and
work correctly even when trying to allocate too much memory.
parent
f540ea64
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
135 additions
and
101 deletions
+135
-101
kernel32.spec
dlls/kernel/kernel32.spec
+1
-0
int21.c
dlls/winedos/int21.c
+27
-1
miscemu.h
include/miscemu.h
+1
-1
global.c
memory/global.c
+43
-9
dosmem.c
msdos/dosmem.c
+63
-73
int21.c
msdos/int21.c
+0
-17
No files found.
dlls/kernel/kernel32.spec
View file @
54f377c6
...
...
@@ -1142,6 +1142,7 @@
@ cdecl DOSMEM_FreeBlock(ptr) DOSMEM_FreeBlock
@ cdecl DOSMEM_GetBlock(long ptr) DOSMEM_GetBlock
@ cdecl DOSMEM_Init(long) DOSMEM_Init
@ cdecl DOSMEM_ResizeBlock(ptr long long) DOSMEM_ResizeBlock
@ cdecl DRIVE_OpenDevice(long long) DRIVE_OpenDevice
@ stdcall INT_Int21Handler(ptr) INT_Int21Handler
@ cdecl LOCAL_Alloc(long long long) LOCAL_Alloc
...
...
dlls/winedos/int21.c
View file @
54f377c6
...
...
@@ -1365,7 +1365,33 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
break
;
case
0x4a
:
/* RESIZE MEMORY BLOCK */
INT_Int21Handler
(
context
);
TRACE
(
"RESIZE MEMORY segment %04lX to %d paragraphs
\n
"
,
context
->
SegEs
,
BX_reg
(
context
)
);
{
DWORD
newsize
=
(
DWORD
)
BX_reg
(
context
)
<<
4
;
if
(
!
ISV86
(
context
)
&&
DOSVM_IsWin16
())
{
FIXME
(
"Resize memory block - unsupported under Win16
\n
"
);
}
else
{
LPVOID
address
=
(
void
*
)((
DWORD
)
context
->
SegEs
<<
4
);
UINT
blocksize
=
DOSMEM_ResizeBlock
(
address
,
newsize
,
FALSE
);
if
(
blocksize
==
(
UINT
)
-
1
)
{
SET_CFLAG
(
context
);
SET_AX
(
context
,
0x0009
);
/* illegal address */
}
else
if
(
blocksize
!=
newsize
)
{
SET_CFLAG
(
context
);
SET_AX
(
context
,
0x0008
);
/* insufficient memory */
SET_BX
(
context
,
blocksize
>>
4
);
/* new block size */
}
}
}
break
;
case
0x4b
:
/* "EXEC" - LOAD AND/OR EXECUTE PROGRAM */
...
...
include/miscemu.h
View file @
54f377c6
...
...
@@ -169,7 +169,7 @@ extern void DOSMEM_Tick(WORD timer);
extern
WORD
DOSMEM_AllocSelector
(
WORD
);
extern
LPVOID
DOSMEM_GetBlock
(
UINT
size
,
WORD
*
p
);
extern
BOOL
DOSMEM_FreeBlock
(
void
*
ptr
);
extern
LPVOID
DOSMEM_ResizeBlock
(
void
*
ptr
,
UINT
size
,
WORD
*
p
);
extern
UINT
DOSMEM_ResizeBlock
(
void
*
ptr
,
UINT
size
,
BOOL
exact
);
extern
UINT
DOSMEM_Available
(
void
);
extern
LPVOID
DOSMEM_MapRealToLinear
(
DWORD
);
/* real-mode to linear */
extern
LPVOID
DOSMEM_MapDosToLinear
(
UINT
);
/* linear DOS to Wine */
...
...
memory/global.c
View file @
54f377c6
...
...
@@ -308,7 +308,10 @@ HGLOBAL16 WINAPI GlobalReAlloc16(
if
(
!
(
pArena
->
flags
&
GA_MOVEABLE
)
||
!
(
pArena
->
flags
&
GA_DISCARDABLE
)
||
(
pArena
->
lockCount
>
0
)
||
(
pArena
->
pageLockCount
>
0
))
return
0
;
HeapFree
(
GetProcessHeap
(),
0
,
(
void
*
)
pArena
->
base
);
if
(
pArena
->
flags
&
GA_DOSMEM
)
DOSMEM_FreeBlock
(
(
void
*
)
pArena
->
base
);
else
HeapFree
(
GetProcessHeap
(),
0
,
(
void
*
)
pArena
->
base
);
pArena
->
base
=
0
;
/* Note: we rely on the fact that SELECTOR_ReallocBlock won't
...
...
@@ -343,18 +346,43 @@ HGLOBAL16 WINAPI GlobalReAlloc16(
if
(
ptr
&&
(
size
==
oldsize
))
return
handle
;
/* Nothing to do */
if
(
pArena
->
flags
&
GA_DOSMEM
)
newptr
=
DOSMEM_ResizeBlock
(
ptr
,
size
,
NULL
);
{
if
(
DOSMEM_ResizeBlock
(
ptr
,
size
,
TRUE
)
==
size
)
newptr
=
ptr
;
else
if
(
pArena
->
pageLockCount
>
0
)
newptr
=
0
;
else
{
newptr
=
DOSMEM_GetBlock
(
size
,
0
);
if
(
newptr
)
{
memcpy
(
newptr
,
ptr
,
oldsize
);
DOSMEM_FreeBlock
(
ptr
);
}
}
}
else
/* if more then one reader (e.g. some pointer has been given out by GetVDMPointer32W16),
only try to realloc in place */
{
/*
* if more then one reader (e.g. some pointer has been
* given out by GetVDMPointer32W16),
* only try to realloc in place
*/
newptr
=
HeapReAlloc
(
GetProcessHeap
(),
(
pArena
->
pageLockCount
>
0
)
?
HEAP_REALLOC_IN_PLACE_ONLY
:
0
,
ptr
,
size
);
(
pArena
->
pageLockCount
>
0
)
?
HEAP_REALLOC_IN_PLACE_ONLY
:
0
,
ptr
,
size
);
}
if
(
!
newptr
)
{
FIXME
(
"Realloc failed lock %d
\n
"
,
pArena
->
pageLockCount
);
if
(
pArena
->
pageLockCount
<
1
)
{
HeapFree
(
GetProcessHeap
(),
0
,
ptr
);
if
(
pArena
->
flags
&
GA_DOSMEM
)
DOSMEM_FreeBlock
(
(
void
*
)
pArena
->
base
);
else
HeapFree
(
GetProcessHeap
(),
0
,
ptr
);
SELECTOR_FreeBlock
(
sel
);
memset
(
pArena
,
0
,
sizeof
(
GLOBALARENA
)
);
}
...
...
@@ -367,15 +395,21 @@ HGLOBAL16 WINAPI GlobalReAlloc16(
sel
=
SELECTOR_ReallocBlock
(
sel
,
ptr
,
size
);
if
(
!
sel
)
{
HeapFree
(
GetProcessHeap
(),
0
,
ptr
);
if
(
pArena
->
flags
&
GA_DOSMEM
)
DOSMEM_FreeBlock
(
(
void
*
)
pArena
->
base
);
else
HeapFree
(
GetProcessHeap
(),
0
,
ptr
);
memset
(
pArena
,
0
,
sizeof
(
GLOBALARENA
)
);
return
0
;
}
selcount
=
(
size
+
0xffff
)
/
0x10000
;
if
(
!
(
pNewArena
=
GLOBAL_GetArena
(
sel
,
selcount
)))
{
HeapFree
(
GetProcessHeap
(),
0
,
ptr
);
{
if
(
pArena
->
flags
&
GA_DOSMEM
)
DOSMEM_FreeBlock
(
(
void
*
)
pArena
->
base
);
else
HeapFree
(
GetProcessHeap
(),
0
,
ptr
);
SELECTOR_FreeBlock
(
sel
);
return
0
;
}
...
...
msdos/dosmem.c
View file @
54f377c6
...
...
@@ -581,89 +581,79 @@ BOOL DOSMEM_FreeBlock(void* ptr)
/***********************************************************************
* DOSMEM_ResizeBlock
*
* Resize DOS memory block in place. Returns block size or -1 on error.
*
* If exact is TRUE, returned value is either old or requested block
* size. If exact is FALSE, block is expanded even if there is not
* enough space for full requested block size.
*/
LPVOID
DOSMEM_ResizeBlock
(
void
*
ptr
,
UINT
size
,
UINT16
*
pseg
)
UINT
DOSMEM_ResizeBlock
(
void
*
ptr
,
UINT
size
,
BOOL
exact
)
{
char
*
block
=
NULL
;
dosmem_info
*
info_block
=
DOSMEM_InfoBlock
();
dosmem_entry
*
dm
;
dosmem_entry
*
next
;
UINT
blocksize
;
UINT
orgsize
;
if
(
ptr
>=
(
void
*
)(((
char
*
)
DOSMEM_RootBlock
())
+
sizeof
(
dosmem_entry
))
&&
ptr
<
(
void
*
)
DOSMEM_MemoryTop
()
&&
!
((((
char
*
)
ptr
)
-
DOSMEM_dosmem
)
&
0xf
)
)
if
(
ptr
<
(
void
*
)(((
char
*
)
DOSMEM_RootBlock
())
+
sizeof
(
dosmem_entry
))
||
(
ptr
>=
(
void
*
)
DOSMEM_MemoryTop
()
&&
!
((((
char
*
)
ptr
)
-
DOSMEM_dosmem
)
&
0xf
)))
return
(
UINT
)
-
1
;
dm
=
(
dosmem_entry
*
)(((
char
*
)
ptr
)
-
sizeof
(
dosmem_entry
));
if
(
dm
->
size
&
(
DM_BLOCK_FREE
|
DM_BLOCK_TERMINAL
)
)
return
(
UINT
)
-
1
;
next
=
NEXT_BLOCK
(
dm
);
orgsize
=
dm
->
size
&
DM_BLOCK_MASK
;
/* collapse free blocks */
while
(
next
->
size
&
DM_BLOCK_FREE
)
{
dosmem_entry
*
dm
=
(
dosmem_entry
*
)(((
char
*
)
ptr
)
-
sizeof
(
dosmem_entry
));
dm
->
size
+=
sizeof
(
dosmem_entry
)
+
(
next
->
size
&
DM_BLOCK_MASK
);
next
->
size
=
(
DM_BLOCK_FREE
|
DM_BLOCK_TERMINAL
);
next
=
NEXT_BLOCK
(
dm
);
}
if
(
pseg
)
*
pseg
=
((
char
*
)
ptr
-
DOSMEM_dosmem
)
>>
4
;
blocksize
=
dm
->
size
&
DM_BLOCK_MASK
;
if
(
!
(
dm
->
size
&
(
DM_BLOCK_FREE
|
DM_BLOCK_TERMINAL
))
)
{
dosmem_entry
*
next
=
NEXT_BLOCK
(
dm
);
UINT
blocksize
,
orgsize
=
dm
->
size
&
DM_BLOCK_MASK
;
while
(
next
->
size
&
DM_BLOCK_FREE
)
/* collapse free blocks */
{
dm
->
size
+=
sizeof
(
dosmem_entry
)
+
(
next
->
size
&
DM_BLOCK_MASK
);
next
->
size
=
(
DM_BLOCK_FREE
|
DM_BLOCK_TERMINAL
);
next
=
NEXT_BLOCK
(
dm
);
}
blocksize
=
dm
->
size
&
DM_BLOCK_MASK
;
if
(
blocksize
>=
size
)
{
block
=
((
char
*
)
dm
)
+
sizeof
(
dosmem_entry
);
if
(
blocksize
-
size
>
0x20
)
{
/* split dm so that the next one stays
* paragraph-aligned (and next gains free bit) */
dm
->
size
=
(((
size
+
0xf
+
sizeof
(
dosmem_entry
))
&
~
0xf
)
-
sizeof
(
dosmem_entry
));
next
=
(
dosmem_entry
*
)(((
char
*
)
dm
)
+
sizeof
(
dosmem_entry
)
+
dm
->
size
);
next
->
size
=
(
blocksize
-
(
dm
->
size
+
sizeof
(
dosmem_entry
)))
|
DM_BLOCK_FREE
;
}
else
dm
->
size
&=
DM_BLOCK_MASK
;
info_block
->
free
+=
orgsize
-
dm
->
size
;
}
else
{
/* the collapse didn't help, try getting a new block */
block
=
DOSMEM_GetBlock
(
size
,
pseg
);
if
(
block
)
{
/* we got one, copy the old data there (we do need to, right?) */
memcpy
(
block
,
((
char
*
)
dm
)
+
sizeof
(
dosmem_entry
),
(
size
<
orgsize
)
?
size
:
orgsize
);
/* free old block */
info_block
->
blocks
--
;
info_block
->
free
+=
dm
->
size
;
dm
->
size
|=
DM_BLOCK_FREE
;
}
else
{
/* and Bill Gates said 640K should be enough for everyone... */
/* need to split original and collapsed blocks apart again,
* and free the collapsed blocks again, before exiting */
if
(
blocksize
-
orgsize
>
0x20
)
{
/* split dm so that the next one stays
* paragraph-aligned (and next gains free bit) */
dm
->
size
=
(((
orgsize
+
0xf
+
sizeof
(
dosmem_entry
))
&
~
0xf
)
-
sizeof
(
dosmem_entry
));
next
=
(
dosmem_entry
*
)(((
char
*
)
dm
)
+
sizeof
(
dosmem_entry
)
+
dm
->
size
);
next
->
size
=
(
blocksize
-
(
dm
->
size
+
sizeof
(
dosmem_entry
)))
|
DM_BLOCK_FREE
;
}
else
dm
->
size
&=
DM_BLOCK_MASK
;
}
}
}
/*
* If collapse didn't help we either expand block to maximum
* available size (exact == FALSE) or give collapsed blocks
* back to free storage (exact == TRUE).
*/
if
(
blocksize
<
size
)
size
=
exact
?
orgsize
:
blocksize
;
block
=
((
char
*
)
dm
)
+
sizeof
(
dosmem_entry
);
if
(
blocksize
-
size
>
0x20
)
{
/*
* split dm so that the next one stays
* paragraph-aligned (and next gains free bit)
*/
dm
->
size
=
(((
size
+
0xf
+
sizeof
(
dosmem_entry
))
&
~
0xf
)
-
sizeof
(
dosmem_entry
));
next
=
(
dosmem_entry
*
)(((
char
*
)
dm
)
+
sizeof
(
dosmem_entry
)
+
dm
->
size
);
next
->
size
=
(
blocksize
-
(
dm
->
size
+
sizeof
(
dosmem_entry
)))
|
DM_BLOCK_FREE
;
}
else
{
dm
->
size
&=
DM_BLOCK_MASK
;
}
return
(
LPVOID
)
block
;
}
/*
* Adjust available memory if block size changes.
*/
info_block
->
free
+=
orgsize
-
dm
->
size
;
return
size
;
}
/***********************************************************************
* DOSMEM_Available
...
...
msdos/int21.c
View file @
54f377c6
...
...
@@ -1253,23 +1253,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context )
bSetDOSExtendedError
=
!
INT21_GetCurrentDirectory
(
context
);
break
;
case
0x4a
:
/* RESIZE MEMORY BLOCK */
TRACE
(
"RESIZE MEMORY segment %04lX to %d paragraphs
\n
"
,
context
->
SegEs
,
BX_reg
(
context
));
if
(
!
ISV86
(
context
))
FIXME
(
"RESIZE MEMORY probably insufficient implementation. Expect crash soon
\n
"
);
{
LPVOID
*
mem
=
DOSMEM_ResizeBlock
(
DOSMEM_MapDosToLinear
(
context
->
SegEs
<<
4
),
BX_reg
(
context
)
<<
4
,
NULL
);
if
(
mem
)
SET_AX
(
context
,
DOSMEM_MapLinearToDos
(
mem
)
>>
4
);
else
{
SET_CFLAG
(
context
);
SET_AX
(
context
,
0x0008
);
/* insufficient memory */
SET_BX
(
context
,
DOSMEM_Available
()
>>
4
);
/* not quite right */
}
}
break
;
case
0x4e
:
/* "FINDFIRST" - FIND FIRST MATCHING FILE */
TRACE
(
"FINDFIRST mask 0x%04x spec %s
\n
"
,
CX_reg
(
context
),
(
LPCSTR
)
CTX_SEG_OFF_TO_LIN
(
context
,
context
->
SegDs
,
context
->
Edx
));
...
...
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