Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
wine
Manage
Activity
Members
Labels
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Sam Joan Roque-Worcel
wine
Commits
54a8a25b
Commit
54a8a25b
authored
21 years ago
by
Jukka Heinonen
Committed by
Alexandre Julliard
21 years ago
Browse files
Options
Downloads
Patches
Plain Diff
DPMI programs now handle pending events.
parent
e55a4b63
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
dlls/kernel/instr.c
+1
-0
1 addition, 0 deletions
dlls/kernel/instr.c
dlls/kernel/wowthunk.c
+112
-0
112 additions, 0 deletions
dlls/kernel/wowthunk.c
tools/winebuild/relay.c
+54
-0
54 additions, 0 deletions
tools/winebuild/relay.c
with
167 additions
and
0 deletions
dlls/kernel/instr.c
+
1
−
0
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. */
}
...
...
This diff is collapsed.
Click to expand it.
dlls/kernel/wowthunk.c
+
112
−
0
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) */
...
...
@@ -164,6 +181,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
*
...
...
@@ -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
();
...
...
This diff is collapsed.
Click to expand it.
tools/winebuild/relay.c
+
54
−
0
View file @
54a8a25b
...
...
@@ -1043,6 +1043,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
*
...
...
@@ -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
"
);
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment