Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

472 lines
9.6 KiB

  1. include kernel.inc
  2. include gpfix.inc
  3. ifdef WOW
  4. include protect.inc
  5. endif
  6. sBegin DATA
  7. globalW sels, <1> ; end of list is 1 to fool DOS386 DPMI
  8. globalW selscount, <0> ; length of selman16 list
  9. IF KDEBUG
  10. externW ArenaSel
  11. externW SelTableLen
  12. externD SelTableStart
  13. ENDIF
  14. sEnd DATA
  15. sBegin CODE
  16. assumes CS,CODE
  17. assumes DS,NOTHING
  18. assumes ES,NOTHING
  19. assumes FS,NOTHING
  20. assumes GS,NOTHING
  21. externFP AllocSelectorArray
  22. externFP IFreeSelector
  23. externW gdtdsc
  24. ifdef WOW
  25. externNP DPMIProc
  26. endif
  27. .386p
  28. IF 0 ;KDEBUG - WOW doesn't have FastAndDirty... routines from win95 krn32.asm
  29. extern FastAndDirtyIsMovableHandle:far16
  30. ENDIF
  31. WOW_DPMIFUNC_0C equ 04f2h
  32. ;*********************************************************************
  33. ; MapSL - Maps a selector:offset pair to a linear address
  34. ;
  35. ; Arguments: dAddrFar16 - selector:offset to map
  36. ;
  37. ; Returns: eax = linear address
  38. ; dx:ax = linear address
  39. ;
  40. ; Register Usage: eax,ebx,edx
  41. ;
  42. ; *Must preserve es*. Some win32s thunking code depends on this.
  43. ;*********************************************************************
  44. cProc MapSL, <PUBLIC, FAR>
  45. cBegin nogen
  46. mov bx,sp
  47. mov bx, ss:[bx+4+2] ;Get selector
  48. test bl, 4
  49. jz MapSL_mightbegdt
  50. IF 0 ;KDEBUG - WOW doesn't have FastAndDirty... routines from win95 krn32.asm
  51. push bx
  52. push es
  53. xor cx,cx
  54. mov es,cx
  55. push bx
  56. call FastAndDirtyIsMovableHandle
  57. or ax,ax
  58. jz MapSL_memok
  59. mov bx,sp
  60. add bx, 4
  61. mov ax, ss:[bx+4+2] ;Get offending selector
  62. mov dx, ss:[bx+2] ;Get return address seg
  63. mov bx, ss:[bx] ;Get return address off
  64. krDebugOut DEB_ERROR, "*** MapSL(16) called on unfixed selector #ax. Ret addr: #dx:#bx"
  65. MapSL_memok:
  66. pop cx
  67. beg_fault_trap MapSL_bad_es
  68. MapSL_restore_es:
  69. mov es,cx
  70. end_fault_trap
  71. pop bx
  72. jmp MapSL_memchkdone
  73. MapSL_bad_es:
  74. fault_fix_stack
  75. xor cx,cx
  76. jmp MapSL_restore_es
  77. MapSL_memchkdone:
  78. ENDIF ;KDEBUG
  79. mov gs, [gdtdsc]
  80. and bl, not 7 ;Mask ring bits
  81. beg_fault_trap MapSL_fault_Trap
  82. test byte ptr gs:[bx+5], 80h
  83. end_fault_trap
  84. jz MapSL_invalid
  85. mov ah, gs:[bx+7] ; get upper 8 bits base
  86. mov al, gs:[bx+4] ; get next byte of base
  87. shl eax, 16 ; move to proper place
  88. mov ax, gs:[bx+2] ; get lower 16 bits of base
  89. xor edx, edx
  90. mov bx, sp
  91. mov dx, ss:[bx+4] ; get offset of current pointer
  92. add eax, edx ; find complete 32 bit base
  93. MapSL_exit2:
  94. xor cx,cx ;Don't give apps access to the LDT
  95. mov gs,cx
  96. MapSL_exit:
  97. ;; dx:ax <- eax
  98. shld edx, eax, 16 ;dx <- hiword of eax
  99. retf 4
  100. ;;--------------------------------------------------------------
  101. ;; Error case: Selector out of range.
  102. ;;--------------------------------------------------------------
  103. MapSL_fault_trap:
  104. fault_fix_stack
  105. IF KDEBUG
  106. mov bx, sp
  107. mov bx, ss:[bx+4+2]
  108. krDebugOut DEB_ERROR, "MapSL(#bx): out of range selector"
  109. ENDIF
  110. xor eax,eax
  111. jmp MapSL_exit2
  112. ;;--------------------------------------------------------------
  113. ;; Error case: Selector not present
  114. ;;--------------------------------------------------------------
  115. MapSL_invalid:
  116. IF KDEBUG
  117. mov bx, sp
  118. mov bx, ss:[bx+4+2]
  119. krDebugOut DEB_ERROR, "MapSL(#bx): selector not present."
  120. ENDIF
  121. xor eax,eax
  122. jmp MapSL_exit2
  123. ;;--------------------------------------------------------------
  124. ;; Potential error case: GDT selector or NULL?
  125. ;;--------------------------------------------------------------
  126. MapSL_mightbegdt:
  127. or bx,bx
  128. jnz MapSL_gdt
  129. ;; Special case: Return original argument.
  130. mov bx,sp
  131. mov eax, ss:[bx+4]
  132. shld edx, eax, 16 ;dx <- hiword of eax
  133. retf 4
  134. ;;--------------------------------------------------------------
  135. ;; Error case: GDT selector
  136. ;;--------------------------------------------------------------
  137. MapSL_gdt:
  138. IF KDEBUG
  139. krDebugOut DEB_ERROR, "***MapSL(16) called on GDT selector #bx"
  140. ENDIF
  141. xor eax,eax
  142. jmp MapSL_exit
  143. cEnd nogen
  144. ;****************************************************************
  145. ; MapLS - Allocate a new 64k limit selector that maps to linear address.
  146. ;
  147. ; Returns: Selector:offset in eax & dx:ax (offset is always zero).
  148. ; *Must preserve es because some win32s thunking code depends on it.*
  149. ;****************************************************************
  150. cProc MapLS, <PUBLIC, FAR>
  151. cBegin nogen
  152. mov bx, sp
  153. mov dx, ss:[bx+4+2]
  154. or dx,dx
  155. jz MapLS_special
  156. mov gs, [gdtdsc]
  157. SetKernelDS fs
  158. mov eax, ss:[bx+2] ;put lo-word in hi-half of eax
  159. mov bx, fs:[sels]
  160. cmp bx, 1
  161. jz MapLS_moresel ;cache is empty: go to slow case
  162. mov cx, gs:[bx] ;remove from linked list
  163. mov fs:[sels], cx
  164. dec fs:[selscount]
  165. MapLS_gotit:
  166. and bl, not 7
  167. or ax, -1 ;Set limit to 64k
  168. mov gs:[bx], eax ;Init low half of descriptor
  169. xchg dh, dl
  170. shl edx, 16 ;Put high 16 bits of base up hi
  171. mov dl, 1+2+16+32+64+128 ;accessed, write, app, ring3, present
  172. rol edx, 8
  173. mov gs:[bx+4], edx ;init upper half of descriptor
  174. mov cx, 1
  175. DPMICALL WOW_DPMIFUNC_0C ; Write shadow LDT entry thru to system LDT.
  176. mov dx, bx
  177. or dl, 7
  178. mov ax, dx
  179. shl eax, 16 ;EAX = DX:AX = NEWSEL:0 = alias
  180. MapLS_exit2:
  181. xor cx,cx
  182. mov gs,cx ;Don't give apps access to LDT
  183. MapLS_exit:
  184. retf 4
  185. UnsetKernelDS fs
  186. MapLS_special:
  187. mov eax, ss:[bx+4]
  188. ;; dx already has correct value
  189. retf 4
  190. UnsetKernelDS fs
  191. ;------------------------------------------------------------------------
  192. ; K16 selman cache is empty. Time to get more from krnl386.
  193. ;------------------------------------------------------------------------
  194. MapLS_moresel: ; we need some more selectors here
  195. push es
  196. ;Don't use more than one here. get_sel always takes
  197. ; multi-selector requests from DPMI, and these
  198. ; usually won't be given back because we'll free
  199. ; them one by one.
  200. cCall AllocSelectorArray, <1>
  201. or ax,ax
  202. jnz MapLS_moreselendloop
  203. ;Uh oh.
  204. krDebugOut DEB_ERROR, "MapLS(16): Couldn't get any more selectors!"
  205. xor ax,ax
  206. ; Fall thru.
  207. MapLS_moreselendloop:
  208. krDebugOut DEB_TRACE, "Selman(16) allocated selector #AX from KRNL386."
  209. pop cx
  210. beg_fault_trap MapLS_bades
  211. MapLS_restore_es:
  212. mov es,cx
  213. end_fault_trap
  214. cwd ; put possible failure code in DX
  215. cwde ; and in EAX
  216. or ax, ax
  217. jz MapLS_exit2
  218. mov gs, [gdtdsc]
  219. SetKernelDS fs
  220. xchg bx,ax
  221. and bl, not 7
  222. push bx
  223. mov bx,sp
  224. add bx, 2
  225. mov dx, ss:[bx+4+2]
  226. mov eax, ss:[bx+2]
  227. pop bx
  228. jmp MapLS_gotit
  229. MapLS_bades:
  230. fault_fix_stack
  231. xor cx,cx
  232. jmp MapLS_restore_es
  233. UnsetKernelDS fs
  234. cEnd nogen
  235. ;***********************************************************************
  236. ; UnMapLS
  237. ;***********************************************************************
  238. cProc UnMapLS, <PUBLIC, FAR>
  239. cBegin nogen
  240. if KDEBUG
  241. mov bx, sp
  242. push ds
  243. mov bx, ss:[bx+4+2]
  244. or bx,bx
  245. jz UnMapLS_ok
  246. test bl, 4
  247. jz UnMapLS_gdt
  248. or bl, 7
  249. SetKernelDS
  250. mov ax, [gdtdsc]
  251. lsl dx,ax
  252. cmp bx,dx
  253. ja UnMapLS_pastldt
  254. mov ds,ax
  255. UnsetKernelDS
  256. test byte ptr ds:[bx-2], 080h
  257. jz UnMapLS_notpresent
  258. SetKernelDS
  259. and bl, not 7
  260. shr bx, 1
  261. cmp bx, [SelTableLen]
  262. jae UnMapLS_notgh
  263. movzx ebx,bx
  264. add ebx, [SelTableStart]
  265. mov ds, [ArenaSel]
  266. UnsetKernelDS
  267. mov eax, ds:[ebx]
  268. or eax,eax
  269. jnz UnMapLS_gh
  270. UnMapLS_notgh:
  271. ;Fallthru
  272. UnMapLS_ok:
  273. pop ds
  274. endif
  275. mov bx, sp
  276. mov bx, ss:[bx+4+2]
  277. and bl, not 7 ; point to LDT entry
  278. jz UnMapLS_null
  279. xor eax,eax
  280. mov es,eax ;In case es contains selector we're trashing
  281. ; fs and gs are loaded below.
  282. if KDEBUG
  283. mov ax, ss
  284. and al, not 7
  285. cmp ax, bx
  286. je UnMapLS_inuse
  287. xor ax, ax
  288. endif
  289. SetKernelDS fs
  290. mov gs, [gdtdsc]
  291. if KDEBUG
  292. test WORD PTR gs:[bx+5], 80h
  293. jz UnMapLS_invalid
  294. endif
  295. mov ax, fs:[sels]
  296. mov gs:[bx], eax ; linked list of avail sels
  297. xor eax,eax
  298. mov gs:[bx+4], eax ; zero out entry
  299. mov fs:[sels], bx ; new list head sel
  300. inc fs:[selscount]
  301. UnMapLS_checkcount:
  302. if KDEBUG
  303. cmp fs:[selscount], 4
  304. else
  305. cmp fs:[selscount], 42
  306. endif
  307. jb UnMapLS_Null
  308. dec fs:[selscount]
  309. mov bx, fs:[sels]
  310. mov ax, gs:[bx]
  311. mov fs:[sels],ax
  312. ; Make it look like a valid limit-1 selector so FreeSelector doesn't
  313. ; free the ones after it.
  314. mov dword ptr gs:[bx], 1
  315. mov dword ptr gs:[bx+4], 0000f300h
  316. or bx, 7
  317. push ds
  318. push es
  319. push fs
  320. push gs
  321. push bx
  322. xor cx,cx ;Just in case of one these registers contained
  323. mov ds,cx ;the segment being freed.
  324. mov es,cx
  325. cCall IFreeSelector,<bx>
  326. pop bx
  327. pop gs
  328. pop fs
  329. pop cx
  330. beg_fault_trap UnMapLS_bades
  331. UnMapLS_restore_es:
  332. mov es,cx
  333. end_fault_trap
  334. pop cx
  335. beg_fault_trap UnMapLS_badds
  336. UnMapLS_restore_ds:
  337. mov ds,cx
  338. end_fault_trap
  339. krDebugOut DEB_TRACE, "Selman(16) returning selector #BX to KRNL386"
  340. jmp UnMapLS_checkcount
  341. UnMapLS_null:
  342. xor eax, eax ; EAX = DX:AX = 0 (OK)
  343. cwd
  344. mov gs,ax ; Cut off access to LDT
  345. UnMapLS_exit:
  346. retf 4
  347. UnMapLS_bades:
  348. fault_fix_stack
  349. xor cx,cx
  350. jmp UnMapLS_restore_es
  351. UnMapLS_badds:
  352. fault_fix_stack
  353. xor cx,cx
  354. jmp UnMapLS_restore_ds
  355. if KDEBUG
  356. UnMapLS_invalid:
  357. krDebugOut DEB_ERROR, "UnMapLS(#bx) invalid selector"
  358. or al, 1 ; AX != 0
  359. jmps UnMapLS_exit
  360. UnMapLS_inuse:
  361. krDebugOut DEB_ERROR, "UnMapLS(#bx) attempting to free ss"
  362. or al, 1 ; AX != 0
  363. jmps UnMapLS_exit
  364. UnMapLS_gdt:
  365. mov bx,sp
  366. add bx,2
  367. mov bx, ss:[bx+4+2]
  368. krDebugOut DEB_ERROR, "UnMapLS(#bx) GDT selector. Type 'k'"
  369. jmp UnMapLS_ok ;in trouble if ignores this.
  370. UnMapLS_pastldt:
  371. mov bx,sp
  372. add bx,2
  373. mov bx, ss:[bx+4+2]
  374. krDebugOut DEB_ERROR, "UnMapLS(#bx) Selector out of range. Type 'k'"
  375. jmp UnMapLS_ok ;in trouble if ignores this.
  376. UnMapLS_notpresent:
  377. mov bx,sp
  378. add bx,2
  379. mov bx, ss:[bx+4+2]
  380. krDebugOut DEB_ERROR, "UnMapLS(#bx) Selector not present. Probably part of a freelist! Type 'k' and '.wl'"
  381. jmp UnMapLS_ok ;in trouble if ignores this.
  382. UnMapLS_gh:
  383. mov bx,sp
  384. add bx,2
  385. mov bx, ss:[bx+4+2]
  386. krDebugOut DEB_ERROR, "UnMapLS(#bx) Selector is a global handle! Type 'k' and '.dg'"
  387. jmp UnMapLS_ok ;in trouble if ignores this.
  388. endif
  389. cEnd nogen
  390. sEnd CODE
  391. end