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
54a8a25b
Commit
54a8a25b
authored
Mar 16, 2004
by
Jukka Heinonen
Committed by
Alexandre Julliard
Mar 16, 2004
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
DPMI programs now handle pending events.
parent
e55a4b63
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
167 additions
and
0 deletions
+167
-0
instr.c
dlls/kernel/instr.c
+1
-0
wowthunk.c
dlls/kernel/wowthunk.c
+112
-0
relay.c
tools/winebuild/relay.c
+54
-0
No files found.
dlls/kernel/instr.c
View file @
54a8a25b
...
...
@@ -824,6 +824,7 @@ DWORD INSTR_EmulateInstruction( EXCEPTION_RECORD *rec, CONTEXT86 *context )
context
->
Eip
+=
prefixlen
+
1
;
if
(
NtCurrentTeb
()
->
vm86_pending
)
{
NtCurrentTeb
()
->
vm86_pending
=
0
;
rec
->
ExceptionCode
=
EXCEPTION_VM86_STI
;
break
;
/* Handle the pending event. */
}
...
...
dlls/kernel/wowthunk.c
View file @
54a8a25b
...
...
@@ -83,6 +83,9 @@ extern void Call16_Ret_Start(), Call16_Ret_End();
extern
void
CallTo16_Ret
();
extern
void
CALL32_CBClient_Ret
();
extern
void
CALL32_CBClientEx_Ret
();
extern
void
DPMI_PendingEventCheck
();
extern
void
DPMI_PendingEventCheck_Cleanup
();
extern
void
DPMI_PendingEventCheck_Return
();
extern
DWORD
CallTo16_DataSelector
;
extern
SEGPTR
CALL32_CBClient_RetAddr
;
extern
SEGPTR
CALL32_CBClientEx_RetAddr
;
...
...
@@ -94,6 +97,11 @@ extern void RELAY16_InitDebugLists(void);
static
LONG
CALLBACK
vectored_handler
(
EXCEPTION_POINTERS
*
ptrs
);
static
SEGPTR
call16_ret_addr
;
/* segptr to CallTo16_Ret routine */
static
WORD
dpmi_checker_selector
;
static
DWORD
dpmi_checker_offset_call
;
static
DWORD
dpmi_checker_offset_cleanup
;
static
DWORD
dpmi_checker_offset_return
;
/***********************************************************************
* WOWTHUNK_Init
*/
...
...
@@ -114,6 +122,15 @@ BOOL WOWTHUNK_Init(void)
CALL32_CBClientEx_RetAddr
=
MAKESEGPTR
(
codesel
,
(
char
*
)
CALL32_CBClientEx_Ret
-
(
char
*
)
Call16_Ret_Start
);
/* Prepare selector and offsets for DPMI event checking. */
dpmi_checker_selector
=
codesel
;
dpmi_checker_offset_call
=
(
char
*
)
DPMI_PendingEventCheck
-
(
char
*
)
Call16_Ret_Start
;
dpmi_checker_offset_cleanup
=
(
char
*
)
DPMI_PendingEventCheck_Cleanup
-
(
char
*
)
Call16_Ret_Start
;
dpmi_checker_offset_return
=
(
char
*
)
DPMI_PendingEventCheck_Return
-
(
char
*
)
Call16_Ret_Start
;
if
(
TRACE_ON
(
relay
)
||
TRACE_ON
(
snoop
))
RELAY16_InitDebugLists
();
/* setup emulation of protected instructions from 32-bit code (only for Win9x versions) */
...
...
@@ -165,6 +182,75 @@ static BOOL fix_selector( CONTEXT *context )
/*************************************************************
* insert_event_check
*
* Make resuming the context check for pending DPMI events
* before the original context is restored. This is required
* because DPMI events are asynchronous, they are blocked while
* Wine 32-bit code is being executed and we want to prevent
* a race when returning back to 16-bit or 32-bit DPMI context.
*/
static
void
insert_event_check
(
CONTEXT
*
context
)
{
char
*
stack
=
wine_ldt_get_ptr
(
context
->
SegSs
,
context
->
Esp
);
if
(
context
->
SegCs
==
dpmi_checker_selector
&&
context
->
Eip
>=
dpmi_checker_offset_call
&&
context
->
Eip
<=
dpmi_checker_offset_cleanup
)
{
/*
* Nested call. Stack will be preserved.
*/
}
else
if
(
context
->
SegCs
==
dpmi_checker_selector
&&
context
->
Eip
==
dpmi_checker_offset_return
)
{
/*
* Nested call. We have just finished popping the fs
* register, lets put it back into stack.
*/
stack
-=
sizeof
(
WORD
);
*
(
WORD
*
)
stack
=
context
->
SegFs
;
context
->
Esp
-=
2
;
}
else
{
/*
* Call is not nested.
* Push modified registers into stack.
* These will be popped by the assembler stub.
*/
stack
-=
sizeof
(
DWORD
);
*
(
DWORD
*
)
stack
=
context
->
EFlags
;
stack
-=
sizeof
(
DWORD
);
*
(
DWORD
*
)
stack
=
context
->
SegCs
;
stack
-=
sizeof
(
DWORD
);
*
(
DWORD
*
)
stack
=
context
->
Eip
;
stack
-=
sizeof
(
WORD
);
*
(
WORD
*
)
stack
=
context
->
SegFs
;
context
->
Esp
-=
14
;
}
/*
* Modify the context so that we jump into assembler stub.
* TEB access is made easier by providing the stub
* with the correct fs register value.
*/
context
->
SegCs
=
dpmi_checker_selector
;
context
->
Eip
=
dpmi_checker_offset_call
;
context
->
SegFs
=
wine_get_fs
();
}
/*************************************************************
* call16_handler
*
* Handler for exceptions occurring in 16-bit code.
...
...
@@ -191,6 +277,15 @@ static DWORD call16_handler( EXCEPTION_RECORD *record, EXCEPTION_REGISTRATION_RE
SEGPTR
gpHandler
;
DWORD
ret
=
INSTR_EmulateInstruction
(
record
,
context
);
/*
* Insert check for pending DPMI events. Note that this
* check must be inserted after instructions have been
* emulated because the instruction emulation requires
* original CS:IP and the emulation may change TEB.dpmi_vif.
*/
if
(
NtCurrentTeb
()
->
dpmi_vif
)
insert_event_check
(
context
);
if
(
ret
!=
ExceptionContinueSearch
)
return
ret
;
/* check for Win16 __GP handler */
...
...
@@ -212,6 +307,10 @@ static DWORD call16_handler( EXCEPTION_RECORD *record, EXCEPTION_REGISTRATION_RE
}
}
}
else
if
(
record
->
ExceptionCode
==
EXCEPTION_VM86_STI
)
{
insert_event_check
(
context
);
}
return
ExceptionContinueSearch
;
}
...
...
@@ -547,6 +646,19 @@ BOOL WINAPI K32WOWCallback16Ex( DWORD vpfn16, DWORD dwFlags,
cbArgs
+=
sizeof
(
SEGPTR
);
}
/*
* Start call by checking for pending events.
* Note that wine_call_to_16_regs overwrites context stack
* pointer so we may modify it here without a problem.
*/
if
(
NtCurrentTeb
()
->
dpmi_vif
)
{
context
->
SegSs
=
wine_get_ds
();
context
->
Esp
=
(
DWORD
)
stack
;
insert_event_check
(
context
);
cbArgs
+=
(
DWORD
)
stack
-
context
->
Esp
;
}
_EnterWin16Lock
();
wine_call_to_16_regs
(
context
,
cbArgs
,
call16_handler
);
_LeaveWin16Lock
();
...
...
tools/winebuild/relay.c
View file @
54a8a25b
...
...
@@ -1044,6 +1044,57 @@ static void BuildCallFrom32Regs( FILE *outfile )
/*******************************************************************
* BuildPendingEventCheck
*
* Build a function that checks whether there are any
* pending DPMI events.
*
* Stack layout:
*
* (sp+12) long eflags
* (sp+6) long cs
* (sp+2) long ip
* (sp) word fs
*
* On entry to function, fs register points to a valid TEB.
* On exit from function, stack will be popped.
*/
void
BuildPendingEventCheck
(
FILE
*
outfile
)
{
/* Function header */
function_header
(
outfile
,
"DPMI_PendingEventCheck"
);
/* Check for pending events. */
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
testl $0xffffffff,(%d)
\n
"
,
STRUCTOFFSET
(
TEB
,
vm86_pending
)
);
fprintf
(
outfile
,
"
\t
je DPMI_PendingEventCheck_Cleanup
\n
"
);
fprintf
(
outfile
,
"
\t
.byte 0x64
\n\t
testl $0xffffffff,(%d)
\n
"
,
STRUCTOFFSET
(
TEB
,
dpmi_vif
)
);
fprintf
(
outfile
,
"
\t
je DPMI_PendingEventCheck_Cleanup
\n
"
);
/* Process pending events. */
fprintf
(
outfile
,
"
\t
sti
\n
"
);
/* Start cleanup. Restore fs register. */
fprintf
(
outfile
,
".globl DPMI_PendingEventCheck_Cleanup
\n
"
);
fprintf
(
outfile
,
"DPMI_PendingEventCheck_Cleanup:
\n
"
);
fprintf
(
outfile
,
"
\t
popw %%fs
\n
"
);
/* Return from function. */
fprintf
(
outfile
,
".globl DPMI_PendingEventCheck_Return
\n
"
);
fprintf
(
outfile
,
"DPMI_PendingEventCheck_Return:
\n
"
);
fprintf
(
outfile
,
"
\t
iret
\n
"
);
}
/*******************************************************************
* BuildRelays16
*
* Build all the 16-bit relay callbacks
...
...
@@ -1131,6 +1182,9 @@ void BuildRelays16( FILE *outfile )
/* CBClientThunkSLEx return stub */
BuildCallTo32CBClientRet
(
outfile
,
TRUE
);
/* Pending DPMI events check stub */
BuildPendingEventCheck
(
outfile
);
/* End of Call16_Ret segment */
fprintf
(
outfile
,
"
\n\t
.globl "
__ASM_NAME
(
"Call16_Ret_End"
)
"
\n
"
);
fprintf
(
outfile
,
__ASM_NAME
(
"Call16_Ret_End"
)
":
\n
"
);
...
...
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