1 | ; $Id: d32CallGate.asm,v 1.1 2001-02-20 05:00:13 bird Exp $
|
---|
2 | ;
|
---|
3 | ; 32-bit CallGate used to communitcate fast between Ring-3 and Ring-0.
|
---|
4 | ; This module contains all assembly workers for this.
|
---|
5 | ;
|
---|
6 | ; Copyright (c) 2001 knut st. osmundsen (knut.stange.osmundsen@mynd.no)
|
---|
7 | ;
|
---|
8 | ; Project Odin Software License can be found in LICENSE.TXT
|
---|
9 | ;
|
---|
10 |
|
---|
11 | .386p
|
---|
12 |
|
---|
13 |
|
---|
14 | ;
|
---|
15 | ; Header Files
|
---|
16 | ;
|
---|
17 | include devsegdf.inc
|
---|
18 | include devhlp.inc
|
---|
19 |
|
---|
20 |
|
---|
21 | ;
|
---|
22 | ; Exported symbols
|
---|
23 | ;
|
---|
24 | public InitCallGate
|
---|
25 |
|
---|
26 |
|
---|
27 | ;
|
---|
28 | ; extrns
|
---|
29 | ;
|
---|
30 | extrn _Device_Help:dword
|
---|
31 | extrn KMEnterKmodeSEF:near
|
---|
32 | extrn KMExitKmodeSEF8:near
|
---|
33 | extrn Win32kAPIRouter:near
|
---|
34 |
|
---|
35 |
|
---|
36 | ;
|
---|
37 | ; Global Variables
|
---|
38 | ;
|
---|
39 | DATA16 segment
|
---|
40 | CallGateGDT dw 0 ; GDT used for the 32-bit Ring-3 -> Ring-0 call gate.
|
---|
41 | DATA16 ends
|
---|
42 |
|
---|
43 | DATA32 segment
|
---|
44 | GDTR_limit dw ? ; The limit field of the GDTR.
|
---|
45 | GDTR_base dd ? ; The base field of the GDTR. (linear flat address)
|
---|
46 | DATA32 ends
|
---|
47 |
|
---|
48 |
|
---|
49 |
|
---|
50 |
|
---|
51 |
|
---|
52 | CODE32 segment
|
---|
53 | assume cs:CODE32, ds:FLAT ;, es:nothing, ss:nothing
|
---|
54 |
|
---|
55 | ;;
|
---|
56 | ; This function initiates the callgate.
|
---|
57 | ; @cproto extern ULONG _Optlink InitCallGate(void);
|
---|
58 | ; @returns 0 (NO_ERROR) on success.
|
---|
59 | ; appropriate error code on error.
|
---|
60 | ; @uses eax, ecx, edx
|
---|
61 | ; @sketch
|
---|
62 | ; @status
|
---|
63 | ; @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
|
---|
64 | ; @remark
|
---|
65 | InitCallGate proc near
|
---|
66 | push ebp
|
---|
67 | mov ebp, esp
|
---|
68 | sub esp, 10h
|
---|
69 | push edi
|
---|
70 | push esi
|
---|
71 | push ebx
|
---|
72 | push ds
|
---|
73 | push es
|
---|
74 |
|
---|
75 | ;
|
---|
76 | ; Allocate GDT selector for the call gate.
|
---|
77 | ; (seems like this call also allocates 68kb of virtual memory which i don't need.)
|
---|
78 | ;
|
---|
79 | mov di, seg DATA16:CallGateGDT
|
---|
80 | mov es, di
|
---|
81 | mov di, offset DATA16:CallGateGDT
|
---|
82 | mov cx, 1
|
---|
83 | mov dl, DevHlp_AllocGDTSelector
|
---|
84 | jmp far ptr CODE16:Thunk16_AllocGDTSelector
|
---|
85 | Thunk32_AllocGDTSelector::
|
---|
86 | jnc ICG_allocok
|
---|
87 | movzx eax, ax ; We failed, zero high word of eax to return proper return code.
|
---|
88 | jmp ICG_end ; bail out.
|
---|
89 |
|
---|
90 | ;
|
---|
91 | ; We successfully allocate the callgate GDT.
|
---|
92 | ; How we'll find the descriptor entry for it.
|
---|
93 | ;
|
---|
94 | ICG_allocok:
|
---|
95 | pop ds
|
---|
96 | push ds ; restore ds (make sure it's flat)
|
---|
97 | ASSUME ds:FLAT
|
---|
98 | sgdt GDTR_limit ; Get the GDTR content.
|
---|
99 | mov ax, GDTR_limit
|
---|
100 | mov ebx, GDTR_base
|
---|
101 | movzx ecx, CallGateGDT
|
---|
102 | and cx, 0fff8h ; clear the dpl bits and descriptor type bit.
|
---|
103 | cmp cx, ax ; check limit. (paranoia!!!)
|
---|
104 | jl ICG_limitok
|
---|
105 | mov eax, 0ffffffffh ; return failure.
|
---|
106 | jmp ICG_end
|
---|
107 | ICG_limitok:
|
---|
108 | add ebx, ecx ; GDTR_base + selector offset -> flat pointer to selector.
|
---|
109 |
|
---|
110 | ;
|
---|
111 | ; ebx is pointing to the descriptor table entry for my GDT selector.
|
---|
112 | ; Now we'll have to change it into a callgate.
|
---|
113 | ; This is the layout of a callgate descriptor:
|
---|
114 | ; bits
|
---|
115 | ; 0-15 Segment offset low word
|
---|
116 | ; 16-31 Segment selector
|
---|
117 | ; -------second dword-------
|
---|
118 | ; 0-4 Param Count
|
---|
119 | ; 5-7 Reserved (zero)
|
---|
120 | ; 8-11 Selector type - 1100b
|
---|
121 | ; 12 Reserved (UVirt) zero
|
---|
122 | ; 13-14 Descriptor Privelege Level (DPL)
|
---|
123 | ; 15 Present flag / Gate valid.
|
---|
124 | ; 16-31 Segment offset high word.
|
---|
125 | ;
|
---|
126 | mov eax, offset FLAT:Win32kCallGate
|
---|
127 | mov word ptr [ebx], ax ; set low segment offset word
|
---|
128 | shr eax, 10h
|
---|
129 | mov word ptr [ebx + 6], ax ; set high segment offset word
|
---|
130 |
|
---|
131 | mov word ptr [ebx + 4], 1110110000000010b ; set flags and stuff.
|
---|
132 | ; param count: Two (2) - parameter struct and function number
|
---|
133 | ; type: 32-bit call gate
|
---|
134 | ; DPL: Ring-3
|
---|
135 | ; Gate Valid: Yes
|
---|
136 | mov word ptr [ebx + 2], seg FLAT:CODE32 ; Set the selector to FLAT Ring-0 code selector.
|
---|
137 | xor eax, eax ; return successfully.
|
---|
138 |
|
---|
139 | ICG_end:
|
---|
140 | pop ds
|
---|
141 | pop es
|
---|
142 | pop ebx
|
---|
143 | pop esi
|
---|
144 | pop edi
|
---|
145 | leave
|
---|
146 | ret
|
---|
147 | InitCallGate endp
|
---|
148 |
|
---|
149 |
|
---|
150 |
|
---|
151 | ;;
|
---|
152 | ; This is the callgate procedure.
|
---|
153 | ; @cproto none
|
---|
154 | ; @returns return value of the callgate router.
|
---|
155 | ; @param fill inn later....
|
---|
156 | ; @uses eax, ecx, edx
|
---|
157 | ; @sketch
|
---|
158 | ; @status
|
---|
159 | ; @author knut st. osmundsen (knut.stange.osmundsen@mynd.no)
|
---|
160 | ; @remark
|
---|
161 | ; stack frame:
|
---|
162 | ; ---top of stack---
|
---|
163 | ; calling ss 1ch
|
---|
164 | ; calling esp 18h
|
---|
165 | ; pParameter (parameter 1) 14h
|
---|
166 | ; ulFunctionCode (parameter 0) 10h
|
---|
167 | ; calling cs 0ch
|
---|
168 | ; calling eip <-- esp points here upon entry. 8h
|
---|
169 | ; ---top of stack---
|
---|
170 | ; flags (pushf) 4h
|
---|
171 | ; parameter size (push 8h) 0h
|
---|
172 | ; ---I start repushing parameters here.
|
---|
173 | ;
|
---|
174 | ;
|
---|
175 | Win32kCallGate proc near
|
---|
176 | pushf ; Push all flags
|
---|
177 | push 8h ; Size of parameters.
|
---|
178 |
|
---|
179 | call KMEnterKmodeSEF ; This is an OS2 kernel function which does
|
---|
180 | ; kernel entry housekeeping.
|
---|
181 |
|
---|
182 | mov edx, [esp + 14h] ; pParameter (parameter 1)
|
---|
183 | mov eax, [esp + 10h] ; ulFunctionCode (parameter 2)
|
---|
184 | sub esp, 8h ; (Even when using _Oplink we have to reserve space for parameters.)
|
---|
185 | call Win32kAPIRouter ; This is my Ring-0 api. (d32Win32kIOCtl.c)
|
---|
186 | add esp, 8h
|
---|
187 |
|
---|
188 | jmp KMExitKmodeSEF8 ; This a an OS2 kernel function which does
|
---|
189 | ; kernel exist housekeeping.
|
---|
190 | Win32kCallGate endp
|
---|
191 |
|
---|
192 |
|
---|
193 | CODE32 ends
|
---|
194 |
|
---|
195 |
|
---|
196 |
|
---|
197 |
|
---|
198 |
|
---|
199 | CODE16 segment
|
---|
200 | assume cs:CODE16, ds:nothing, ss:nothing, es:nothing
|
---|
201 |
|
---|
202 | ;
|
---|
203 | ; Thunker used by the InitCallGate procedure call the AllocGDTSelector devhelper.
|
---|
204 | ;
|
---|
205 | Thunk16_AllocGDTSelector:
|
---|
206 | call [_Device_Help]
|
---|
207 | jmp far ptr FLAT:Thunk32_AllocGDTSelector
|
---|
208 |
|
---|
209 | CODE16 ends
|
---|
210 |
|
---|
211 | end
|
---|
212 |
|
---|