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.

4650 lines
129 KiB

  1. PAGE ,132
  2. TITLE Windows Protect Mode Routines
  3. .xlist
  4. include kernel.inc
  5. .386p
  6. include protect.inc
  7. include pdb.inc
  8. .list
  9. ifdef WOW
  10. ;
  11. ; the dpmi func 04f1h is idential to function 00h, except that
  12. ; the descriptor base and limit are not initialized to zero.
  13. ;
  14. ;
  15. ; the dpmi func 04f2h is identical to 0ch except that it
  16. ; sets 'count' (in cx) LDTs at one time. The first selector is in
  17. ; register bx. The descriptor data is in gdtdsc[bx], gdtdsc[bx+8]
  18. ; etc. This data is shared between dpmi (dosx.exe) and us and thus
  19. ; need not be passed in es:di
  20. WOW_DPMIFUNC_00 equ 04f1h
  21. WOW_DPMIFUNC_0C equ 04f2h
  22. endif
  23. MovsDsc Macro ;Move (copy) a descriptor (4 words)
  24. cld
  25. movsd
  26. movsd
  27. endm
  28. CheckDS Macro
  29. local okds
  30. if KDEBUG
  31. push ax
  32. mov ax, ds
  33. SetKernelDS
  34. cmp ax, ArenaSel
  35. mov ds, ax
  36. UnSetKernelDS
  37. je short okds
  38. int 3
  39. int 3
  40. okds:
  41. pop ax
  42. endif
  43. endm
  44. CheckLDT Macro selector
  45. if KDEBUG
  46. test selector,SEL_LDT
  47. jnz short @F
  48. int 3
  49. @@:
  50. endif
  51. Endm
  52. DPMICALL MACRO callno
  53. mov ax, callno
  54. call DPMIProc
  55. ENDM
  56. MY_SEL equ 0F00h ; Access word to indicate selector owned by kernel
  57. externW pLocalHeap
  58. DataBegin
  59. ifdef WOW
  60. externW SelectorFreeBlock
  61. externW UserSelArray
  62. externB fBooting
  63. globalW high0c,0
  64. globalD FlatAddressArray,0
  65. endif
  66. externW MyCSSeg
  67. externW WinFlags
  68. externW ArenaSel
  69. externW pGlobalHeap
  70. externW MyCSAlias
  71. extrn kr1dsc:WORD
  72. extrn kr2dsc:WORD
  73. extrn blotdsc:WORD
  74. extrn DemandLoadSel:WORD
  75. extrn FreeArenaList:DWORD
  76. extrn FreeArenaCount:DWORD
  77. extrn HighestArena:DWORD
  78. extrn temp_arena:DWORD
  79. extrn SelTableLen:word
  80. extrn SelTableStart:DWORD
  81. extrn temp_sel:WORD
  82. extrn FirstFreeSel:WORD
  83. extrn CountFreeSel:WORD
  84. if ROM
  85. externW selROMTOC
  86. externW selROMLDT
  87. externW sel1stAvail
  88. endif
  89. if ROM
  90. externD lmaHiROM
  91. externD cbHiROM
  92. externD linHiROM
  93. endif
  94. DataEnd
  95. DataBegin INIT
  96. RModeCallStructure STRUC
  97. RMCS_EDI dd 0
  98. RMCS_ESI dd 0
  99. RMCS_EBP dd 0
  100. RMCS_Res dd 0
  101. RMCS_EBX dd 0
  102. RMCS_EDX dd 0
  103. RMCS_ECX dd 0
  104. RMCS_EAX dd 0
  105. RMCS_Flags dw 0
  106. RMCS_ES dw 0
  107. RMCS_DS dw 0
  108. RMCS_FS dw 0
  109. RMCS_GS dw 0
  110. RMCS_IP dw 0
  111. RMCS_CS dw 0
  112. RMCS_SP dw 0
  113. RMCS_SS dw 0
  114. RModeCallStructure ENDS
  115. MyCallStruc RModeCallStructure <>
  116. globalD lpProc,0
  117. if ROM
  118. externW gdtdsc
  119. endif
  120. public MS_DOS_Name_String
  121. MS_DOS_Name_String db "MS-DOS", 0
  122. DataEnd INIT
  123. externFP IGlobalFree
  124. externFP IGlobalAlloc
  125. ifdef WOW
  126. externFP kSYSERRORBOX
  127. externFP VirtualAlloc
  128. endif
  129. sBegin CODE
  130. assumes cs,CODE
  131. assumes ds,nothing
  132. externNP genter
  133. extrn GrowHeapDib: FAR
  134. extrn LocalNotifyDib: FAR
  135. extrn LocalNotifyDefault: FAR
  136. extrn FreeHeapDib: FAR
  137. externNP gleave
  138. extrn IGlobalFix:FAR ;Far calls in this segment
  139. extrn GlobalHandleNorip:FAR
  140. extrn IGlobalFlags:FAR
  141. extrn IGlobalHandle: FAR
  142. extrn Free_Object2: FAR
  143. extrn mycsds:WORD
  144. ife ROM
  145. extrn gdtdsc:WORD
  146. endif
  147. ifdef WOW
  148. externD prevInt31proc
  149. endif
  150. sEnd CODE
  151. sBegin INITCODE
  152. assumes cs,CODE
  153. assumes ds,nothing
  154. ;=======================================================================;
  155. ; ;
  156. ; 386 PROTECTED MODE INITIALISATION ROUTINES ;
  157. ; ;
  158. ;=======================================================================;
  159. ife ROM
  160. ; this function is not used in ROM since DOSX switches to Pmode before
  161. ; jumping to kernel. this means the enhanced mode loader will have
  162. ; to do something similar...
  163. ;-----------------------------------------------------------------------;
  164. ; SwitchToPMODE ;
  165. ; ;
  166. ; Entry: ;
  167. ; In Real or Virtual Mode ;
  168. ; ES -> PSP ;
  169. ; ;
  170. ; Returns: ;
  171. ; In Protect Mode ;
  172. ; BX -> LDT selector ;
  173. ; SI -> Segment of start of available memory ;
  174. ; ES -> PSP ;
  175. ; ;
  176. ; Error Returns: ;
  177. ; Exits via DOS call 4Ch ;
  178. ; ;
  179. ; Registers Preserved: ;
  180. ; ;
  181. ; ;
  182. ; Registers Destroyed: ;
  183. ; ;
  184. ; Calls: ;
  185. ; ;
  186. ; History: ;
  187. ; ;
  188. ;-----------------------------------------------------------------------;
  189. assumes ds,DATA
  190. assumes es,nothing
  191. cProc SwitchToPMODE,<PUBLIC,NEAR>
  192. cBegin nogen
  193. push cx
  194. push es ; Current PSP
  195. mov ax, 1687h
  196. int 2Fh ; Get PMODE switch entry
  197. or ax, ax ; Can we do it?
  198. jnz NoPMODE
  199. xor bh, bh ; Set CPU type now
  200. cmp cl, 3 ; At least a 386?
  201. jb NoPMODE
  202. mov bl,WF_CPU386
  203. je short @F ; If 386
  204. mov bl,WF_CPU486 ; No, assume 486 for now
  205. @@:
  206. mov WinFlags, bx ; Save away CPU type
  207. mov word ptr [lpProc][0], di
  208. mov word ptr [lpProc][2], es
  209. pop ax ; PSP
  210. add ax, 10h ; Skip the PSP
  211. mov es, ax ; Give this to the DOS extender
  212. add si, ax ; Start of memory available to us
  213. ; THIS IS IT FOLKS!
  214. xor ax, ax ; 16-bit app
  215. call [lpProc] ; Switch to PROTECTED mode
  216. jc NoPMODE ; No, still Real/Virtual mode
  217. mov ax, cs
  218. and al, 7 ; LDT, Ring 3
  219. cmp al, 7
  220. jne short BadDPMI ; Insist on Ring 3!
  221. mov bx, cs ; Allocate CS Alias
  222. DPMICALL 000Ah
  223. mov MyCSAlias, ax ; Save CS Alias in DS
  224. mov bx, ds ; Use alias to update code seg var
  225. mov ds, ax
  226. assumes ds, CODE
  227. mov MyCSDS, bx ; The DS selector
  228. mov ds, bx
  229. ReSetKernelDS
  230. push es
  231. push si
  232. mov ax, 168Ah ; See if we have MS-DOS extensions
  233. mov si, dataoffset MS_DOS_Name_String
  234. int 2Fh ; DS:SI -> MS-DOS string
  235. cmp al, 8Ah ; Have extensions?
  236. je short BadDPMI ; no extensions, screwed
  237. mov [lpProc][0], di ; Save CallBack address
  238. mov [lpProc][2], es
  239. mov ax, 0100h ; Get base of LDT
  240. call [lpProc]
  241. jc short NoLDTParty
  242. verw ax ; Writeable?
  243. jnz short NoLDTParty ; nope, don't bother with it yet
  244. mov es, MyCSAlias
  245. assumes es,CODE
  246. mov gdtdsc, ax
  247. assumes es,nothing
  248. NoLDTParty:
  249. pop si
  250. pop es
  251. push si ; Unlock all of our memory
  252. ifndef WOW ; For WOW its all pageable
  253. movzx ebx, si
  254. shl ebx, 4 ; Linear address of start of our memory
  255. movzx esi, es:[PDB_block_len] ; End of our memory
  256. shl esi, 4
  257. sub esi, ebx ; Size of our block
  258. mov di, si
  259. shr esi, 10h
  260. mov cx, bx
  261. shr ebx, 10h
  262. mov ax, 0602h
  263. int 31h ; Mark region as pageable.
  264. endif
  265. pop bx
  266. mov ax, 2 ; Convert start of memory to selector
  267. int 31h
  268. mov si, ax
  269. xor bx, bx
  270. pop cx
  271. ret
  272. BadDPMI:
  273. ;
  274. ; Call real/virtual mode to whine
  275. ;
  276. xor cx, cx ; Nothing on stack to copy
  277. xor bh, bh ; Flags to DPMI
  278. mov ax, MyCSSeg
  279. mov MyCallStruc.RMCS_DS, ax ; Real mode DS will be parent PDB
  280. mov MyCallStruc.RMCS_ES, cx ; Real mode ES will be 0
  281. mov MyCallStruc.RMCS_CS, ax ; Real mode CS
  282. mov MyCallStruc.RMCS_IP, codeoffset RModeCode ; Real mode IP
  283. smov es, ds
  284. mov di, dataOffset MyCallStruc ; ES:DI points to call structure
  285. mov ax, 0301h ; Call Real Mode Procedure
  286. int 31h
  287. jmps GoodBye
  288. RModeCode:
  289. mov dx, codeoffset szInadequate
  290. mov ah, 9
  291. int 21h
  292. retf
  293. ;Inadequate:
  294. ; DB 'KRNL386: Inadequate DPMI Server',13,10,'$'
  295. externB <szNoPMode, szInadequate>
  296. NoPMODE: ; NOTE: stack trashed...
  297. ifdef WOW
  298. ;** Put Up a Dialog Box If we fail to Enter Protect Mode
  299. ;** Prepare the dialog box
  300. push cs ;In our DS
  301. push codeOFFSET szNoPMode ; -> unable to enter Prot Mode
  302. push ds
  303. externB <syserr>
  304. push dataOffset syserr ;Caption
  305. push 0 ;No left button
  306. push SEB_CLOSE + SEB_DEFBUTTON ;Button 1 style
  307. push 0 ;No right button
  308. call kSYSERRORBOX ;Put up the system error message
  309. externNP ExitKernel
  310. jmp ExitKernel
  311. else ; Not WOW
  312. mov dx, codeoffset szNoPMode
  313. ; call complain
  314. ; DB 'KRNL386: Unable to enter Protected Mode',13,10,'$'
  315. ;complain:
  316. ; pop dx
  317. push cs
  318. pop ds ; DS:DX -> error message
  319. mov ah,9 ; Print error message
  320. int 21h
  321. endif; WOW
  322. GoodBye:
  323. mov ax, 4CFFh
  324. int 21h
  325. cEnd nogen
  326. endif
  327. ;-----------------------------------------------------------------------;
  328. ; LDT_Init ;
  329. ; ;
  330. ; Entry: ;
  331. ; DS -> CS ;
  332. ; ;
  333. ; Returns: ;
  334. ; ;
  335. ; Error Returns: ;
  336. ; ;
  337. ; Registers Preserved: ;
  338. ; AX,BX,CX,DX,DI,SI,DS,ES ;
  339. ; ;
  340. ; Registers Destroyed: ;
  341. ; ;
  342. ; Calls: ;
  343. ; ;
  344. ; History: ;
  345. ; ;
  346. ;-----------------------------------------------------------------------;
  347. cProc LDT_Init,<PUBLIC,NEAR>,<ax,bx,cx,di,es>
  348. cBegin
  349. ReSetKernelDS
  350. cmp gdtdsc, 0
  351. jz short SlowAllocation
  352. ;
  353. ; Scan LDT for free selectors and
  354. ; put on a linked list
  355. ;
  356. mov es, gdtdsc
  357. mov cx, 1
  358. DPMICALL 0000h ; Get selector from win386
  359. and al, NOT SEG_RING_MASK
  360. mov FirstFreeSel, ax ; Set up header
  361. mov si, ax
  362. mov word ptr es:[si], -1
  363. mov word ptr es:[si].dsc_access, MY_SEL ; MINE!
  364. mov cx, es
  365. lsl ecx, ecx ; limit of LDT
  366. xor eax, eax
  367. steal_sels:
  368. mov di, si ; prev selector in list
  369. not_this_one:
  370. add si, DSC_LEN ; use add for flags
  371. jz short end_ldt
  372. cmp si, cx
  373. ja short end_ldt
  374. cmp dword ptr es:[si], eax
  375. jne not_this_one
  376. cmp dword ptr es:[si][4], eax
  377. jne not_this_one
  378. mov word ptr es:[di], si ; Link into list
  379. mov word ptr es:[si].dsc_access, MY_SEL ; MINE!
  380. inc CountFreeSel
  381. jmps steal_sels
  382. end_ldt:
  383. mov word ptr es:[di], -1
  384. SlowAllocation:
  385. push es ; Get random selectors
  386. smov es, ds
  387. ReSetKernelDS es
  388. UnSetKernelDS
  389. ; Could get 3 selectors at once here,
  390. ; but get_sel is more efficient for just 1
  391. mov cx, 1 ; Argument to get_sel
  392. call get_sel
  393. or si, SEG_RING
  394. mov kr1dsc, si
  395. call get_sel
  396. mov kr2dsc, si
  397. call get_sel
  398. mov blotdsc, si
  399. call get_sel
  400. or si, SEG_RING
  401. mov DemandLoadSel, si ; for demand loading segments
  402. smov ds, es
  403. pop es
  404. UnSetKernelDS es
  405. cEnd
  406. sEnd INITCODE
  407. sBegin CODE
  408. assumes cs,CODE
  409. assumes ds,nothing
  410. ;=======================================================================;
  411. ; ;
  412. ; SELECTOR ALLOCATION/DEALLOCATION ROUTINES ;
  413. ; ;
  414. ;=======================================================================;
  415. ;-----------------------------------------------------------------------;
  416. ; AllocSelector
  417. ;
  418. ;
  419. ; Entry:
  420. ;
  421. ; Returns:
  422. ; AX = 0 if out of selectors
  423. ;
  424. ; Registers Destroyed:
  425. ;
  426. ; History:
  427. ; Thu 08-Dec-1988 14:17:38 -by- David N. Weise [davidw]
  428. ; Wrote it!
  429. ;-----------------------------------------------------------------------;
  430. assumes ds,nothing
  431. assumes es,nothing
  432. ifdef WOW
  433. labelFP <PUBLIC,AllocSelectorWOW>
  434. mov ax, 1
  435. jmps AllocSelectorWorker
  436. labelFP <PUBLIC,AllocSelector>
  437. xor ax, ax
  438. ; fall through
  439. cProc AllocSelectorWorker,<PUBLIC,FAR>,<di,si,es>
  440. parmW selector
  441. localV OldDsc,DSC_LEN
  442. localW fDontSetDescriptor
  443. cBegin
  444. mov fDontSetDescriptor, ax
  445. else
  446. cProc AllocSelector,<PUBLIC,FAR>,<di,si,es>
  447. parmW selector
  448. localV OldDsc,DSC_LEN
  449. cBegin
  450. endif
  451. mov cx, 1
  452. lsl ecx, dword ptr selector
  453. jz short as_present
  454. call get_sel ; He passed in some junk, give him
  455. ifdef WOW ; just one selector...
  456. ; If we have a good selector, use DPMI to write it through to the
  457. ; system LDT before giving it to an application to use.
  458. jz short as_exit1
  459. mov ax, [bp+4] ; Get caller CS.
  460. cmp ax, IGROUP ; Don't write thru if it's KRNL386 calling.
  461. je short as_exit
  462. cmp ax, _NRESTEXT
  463. je short as_exit
  464. cmp ax, _MISCTEXT
  465. je short as_exit
  466. ;Set shadow LDT entry to known state.
  467. push bx
  468. push ds
  469. mov ds, gdtdsc ; Get shadow LDT in DS
  470. UnSetKernelDS
  471. mov bx, si
  472. mov [bx].dsc_limit, 00h ; Set entry to: BASE = 0, LIMIT = 0, BYTES,
  473. mov [bx].dsc_lbase, 00h ; DPL = 3, PRESENT, DATA
  474. mov [bx].dsc_mbase, 00h
  475. mov [bx].dsc_hbase, 00h
  476. mov ax, DSC_DATA+DSC_PRESENT
  477. mov word ptr [bx].dsc_access, ax
  478. pop ds
  479. DPMICALL WOW_DPMIFUNC_0C ; Write shadow LDT entry thru to system LDT.
  480. pop bx
  481. jmps as_exit
  482. else
  483. jnz short as_exit ; just one selector...
  484. jmps as_exit1
  485. endif
  486. as_present:
  487. Limit_To_Selectors ecx
  488. call get_sel
  489. jz short as_exit1
  490. ifdef WOW
  491. test fDontSetDescriptor, 1
  492. jnz as_exit
  493. endif
  494. smov es, ss
  495. lea di, OldDsc ; ES:DI points to descriptor
  496. mov bx, selector ; BX gets old selector
  497. push ds
  498. if ROM
  499. SetKernelDS
  500. endif
  501. mov ds, gdtdsc
  502. if ROM
  503. assumes ds,nothing
  504. endif
  505. push si ; Get Descriptor
  506. mov si, bx
  507. and si, not 7
  508. MovsDsc
  509. lea di, [di-DSC_LEN] ; Restore DI
  510. pop si
  511. pop ds
  512. mov bx, si ; BX gets new selector
  513. or bl, SEG_RING
  514. call fill_in_selector_array ; and set new array to match
  515. as_exit:
  516. or si, SEG_RING
  517. as_exit1:
  518. mov ax,si
  519. cEnd
  520. ;-----------------------------------------------------------------------;
  521. ; AllocResSelArray - Allocate a resource Selector array (see resaux) ;
  522. ; Combination of AllocSelectorArray + SetResourceOwner;
  523. ; Entry: ;
  524. ; nSels = # selectors required ;
  525. ; parmW owner ;
  526. ; ;
  527. ; ;
  528. ; ;
  529. ; get_sel - get an array of selectors ;
  530. ; ;
  531. ; Entry: ;
  532. ; CX = # selectors required ;
  533. ; ;
  534. ; Returns: ;
  535. ; SI = First Selector ;
  536. ; DS = LDT ;
  537. ; ZF = 0 ;
  538. ; ;
  539. ; Error Returns: ;
  540. ; SI = 0 ;
  541. ; ZF = 1 ;
  542. ; ;
  543. ; Registers Preserved: ;
  544. ; DI,ES ;
  545. ; ;
  546. ; Registers Destroyed: ;
  547. ; ;
  548. ; Calls: ;
  549. ; ;
  550. ; History: ;
  551. ; mattfe March 30th 1993 - WOW Specific Routine, by combining the two ;
  552. ; routines I can reduce the number of DPMI calls by 40/1 for loading ;
  553. ; a typical app. ;
  554. ;-----------------------------------------------------------------------;
  555. ifdef WOW
  556. assumes ds, nothing
  557. assumes es, nothing
  558. cProc AllocResSelArray,<PUBLIC,NEAR>,<cx,si,di,es,ds>
  559. parmW nSels
  560. parmW owner
  561. cBegin
  562. mov cx, nSels
  563. call get_sel
  564. mov ax, si
  565. jz short ARSA_fail
  566. or si, SEG_RING
  567. mov bx, si
  568. mov dx, cx
  569. push ds
  570. mov ds, gdtdsc
  571. push bx
  572. and bl, not 7
  573. ;; For the first selector mark it with the resource owner
  574. mov cx, owner
  575. mov ds:[bx].dsc_owner, cx
  576. mov word ptr ds:[bx].dsc_access, (DSC_DISCARDABLE SHL 8) + DSC_DATA
  577. mov cx,nSels
  578. mov ds:[bx].dsc_hbase, cl ; Save number of selectors here
  579. mov cx, DSC_DATA+DSC_PRESENT
  580. lea bx, [bx+DSC_LEN]
  581. dec dx
  582. jz ASRA_CallNT
  583. ARSA_fill_in_access:
  584. mov word ptr ds:[bx].dsc_access, cx
  585. lea bx, [bx+DSC_LEN]
  586. dec dx
  587. jnz ARSA_fill_in_access
  588. ASRA_CallNT:
  589. mov bx,si ; First Selector
  590. mov cx,nSels ; Count
  591. DPMICALL WOW_DPMIFUNC_0C
  592. SetKernelDS
  593. mov ds, pGlobalHeap
  594. UnSetKernelDS
  595. cCall AssociateSelector32,<si,0,owner> ; And save in selector table
  596. pop ax ; Return first sel
  597. pop ds
  598. ARSA_fail:
  599. cEnd
  600. endif ; WOW
  601. ;-----------------------------------------------------------------------;
  602. ; AllocSelectorArray - external entry for get_sel ;
  603. ; Entry: ;
  604. ; nSels = # selectors required ;
  605. ; ;
  606. ; get_sel - get an array of selectors ;
  607. ; ;
  608. ; Entry: ;
  609. ; CX = # selectors required ;
  610. ; ;
  611. ; Returns: ;
  612. ; SI = First Selector ;
  613. ; DS = LDT ;
  614. ; ZF = 0 ;
  615. ; ;
  616. ; Error Returns: ;
  617. ; SI = 0 ;
  618. ; ZF = 1 ;
  619. ; ;
  620. ; Registers Preserved: ;
  621. ; DI,ES ;
  622. ; ;
  623. ; Registers Destroyed: ;
  624. ; ;
  625. ; Calls: ;
  626. ; ;
  627. ; History: ;
  628. ; ;
  629. ;-----------------------------------------------------------------------;
  630. assumes ds, nothing
  631. assumes es, nothing
  632. cProc AllocSelectorArray,<PUBLIC,FAR>,<si>
  633. parmW nSels
  634. cBegin
  635. mov cx, nSels
  636. call get_sel
  637. mov ax, si
  638. jz short asa_fail
  639. or si, SEG_RING
  640. mov bx, si
  641. mov dx, cx
  642. mov cx, DSC_DATA+DSC_PRESENT
  643. ifdef WOW ; LATER should use single op to update
  644. fill_in_access: ; complete LDT with one call.
  645. DPMICALL 0009h
  646. lea bx, [bx+DSC_LEN]
  647. dec dx
  648. jnz fill_in_access
  649. else
  650. push ds
  651. mov ds, gdtdsc
  652. push bx
  653. and bl, not 7
  654. fill_in_access:
  655. mov word ptr ds:[bx].dsc_access, cx
  656. if 0 ;;ROM and KDEBUG
  657. call CheckROMSelector
  658. endif
  659. lea bx, [bx+DSC_LEN]
  660. dec dx
  661. jnz fill_in_access
  662. pop bx
  663. pop ds
  664. endif; WOW
  665. mov ax, si
  666. asa_fail:
  667. cEnd
  668. if KDEBUG
  669. cProc check_free_sel_list,<PUBLIC,NEAR>
  670. cBegin
  671. pushf
  672. pusha
  673. push ds
  674. call SetKernelDSProc ; Must call direct in this file
  675. ReSetKernelDS
  676. mov cx, CountFreeSel
  677. cmp cx, 2 ; Only check list with more than 1 entry.
  678. jb cfl_ok
  679. inc cx ; Count dummy entry.
  680. mov si, FirstFreeSel ; Pointer to head of list
  681. mov ds, gdtdsc ; Get shadow LDT in DS
  682. UnSetKernelDS
  683. cfl_loop:
  684. mov ax, word ptr [si] ; Get next.
  685. cmp ax, 0FFFFH ; -1 is sentinal
  686. je short cfl_trashed
  687. mov di, si ; Save prev. for debugging.
  688. mov si, ax
  689. loop cfl_loop
  690. mov ax, word ptr [si] ; Get sentinal.
  691. cfl_done:
  692. cmp ax, 0FFFFH ; -1 is sentinal
  693. je short cfl_ok ; Must have sentinal and
  694. cfl_trashed:
  695. kerror 0, <Free sel list is trashed>
  696. cfl_ok:
  697. pop ds
  698. popa
  699. popf
  700. cEnd
  701. endif
  702. cProc get_sel,<PUBLIC,NEAR>
  703. localW MySel
  704. cBegin
  705. pusha
  706. gs_retry_get_sel:
  707. call SetKernelDSProc ; Must call direct in this file
  708. ReSetKernelDS
  709. mov si, FirstFreeSel ; Pointer to head of list
  710. mov ds, gdtdsc
  711. UnSetKernelDS
  712. mov dx, cx ; Sels wanted
  713. mov ax, word ptr [si]
  714. inc ax ; -1 teminated
  715. jz short gs_searchfailed
  716. if KDEBUG
  717. call check_free_sel_list
  718. endif
  719. cmp cx, 1 ; One selector only?
  720. jne short gs_selblock
  721. dec ax
  722. mov di, ax
  723. mov word ptr [di].dsc_access, DSC_USED ; Mark it used
  724. mov di, word ptr [di] ; Unlink it
  725. mov word ptr [si], di
  726. mov si, ax
  727. jmp got_my_sel
  728. gs_selblock: ; Following stolen from DOSX
  729. mov bx, si ; Start of list of free sels
  730. lea si, [si+DSC_LEN] ; Start search here!
  731. mov di, ds
  732. lsl di, di ; limit of LDT
  733. and di, NOT 7
  734. gs_jail:
  735. mov ax, si ; Starting selector
  736. mov cx, dx ; number to check
  737. gs_sb0:
  738. cmp word ptr ds:[si].dsc_access, MY_SEL ; This one free?
  739. jnz short gs_sb1 ; nope, keep looking
  740. lea si, [si+DSC_LEN]
  741. cmp si, di ; Falling off the end?
  742. jae short gs_searchfailed
  743. loop gs_sb0 ; All we wanted?
  744. jmps gs_gotblock
  745. gs_sb1:
  746. lea si, [si+DSC_LEN] ; Restart scan after this selector
  747. cmp si, di
  748. jb short gs_jail
  749. jmps gs_searchfailed
  750. ; Got our block, now blast them out
  751. gs_gotblock: ; of the free list
  752. mov cx, dx ; # selectors
  753. push cx
  754. shl dx, 3 ; Length of our array of selectors
  755. add dx, ax ; First selector after our array
  756. mov si, [bx] ; Next selector in free list
  757. gs_blast:
  758. inc si
  759. jz short gs_blasted ; Gone thru whole list
  760. dec si
  761. cmp si, ax ; See if in range
  762. jb short gs_noblast
  763. cmp si, dx
  764. jb short gs_unlink
  765. gs_noblast:
  766. mov bx, si
  767. mov si, [si] ; Follow the link
  768. jmps gs_blast
  769. gs_unlink: ; This one is in range
  770. mov si, [si] ; Unlink it
  771. mov [bx], si
  772. loop gs_blast ; Stop search when unlinked them all
  773. gs_blasted:
  774. pop cx
  775. mov si, ax
  776. lea si, [si].dsc_access ; Now mark them used
  777. gs_markused:
  778. mov byte ptr [si], DSC_USED
  779. lea si, [si+DSC_LEN]
  780. cmp si, dx
  781. jb short gs_markused
  782. mov si, ax
  783. jmps got_my_sel
  784. gs_searchfailed: ; Failed from our list, try WIN386
  785. mov cx, dx
  786. ;;;%out Take me out later
  787. ;;; mov ds, gdtdsc
  788. ;;; UnSetKernelDS
  789. gs_slow:
  790. ifdef WOW
  791. ;; Calling DPMI to do anything is very slow, so lets grab at minimum 256
  792. ;; selectors at a time, that way we don't have to call again for a while
  793. call SetKernelDSProc ; Must call direct in this file
  794. ReSetKernelDS
  795. push cx
  796. test fbooting,1 ; Don't do optimization during boot
  797. ; since free_Sel will return them to
  798. ; DPMI.
  799. jnz gs_0100
  800. add cx,256 ; get more than we need
  801. DPMICALL 0000h
  802. jc gs_0100 ; Failed, then just grab the required
  803. mov bx, ax ; number.
  804. gs_free_loop:
  805. cCall free_sel,<bx> ; Got the selectors, put them on
  806. lea bx, [bx+DSC_LEN] ; our free list the easy way...
  807. loop gs_free_loop
  808. pop cx
  809. jmp gs_retry_get_sel
  810. gs_0100:
  811. pop cx
  812. endif; WOW
  813. DPMICALL 0000h ; Call DPMI to get one
  814. and al, NOT SEG_RING_MASK
  815. mov si, ax
  816. or si, si ; Did we get it?
  817. jnz short got_dpmi_sel
  818. if KDEBUG
  819. push es
  820. pusha
  821. kerror 0,<Out of selectors>
  822. popa
  823. pop es
  824. jmp gs_exit
  825. else
  826. jmps gs_exit
  827. endif
  828. ; Try to avoid running out of selectors under Enhanced mode by keeping
  829. ; 256 selectors free. This will hopefully allow win386 to grow the
  830. ; LDT while there is still memory to do so.
  831. got_my_sel:
  832. SetKernelDS
  833. sub CountFreeSel, cx
  834. ifndef WOW
  835. ;; See above WOW code which grabs chunks of 256 selectors from DOSX
  836. ;; we don't need to do this.
  837. test byte ptr WinFlags, WF_ENHANCED ; Standard mode can't grow the
  838. jz got_either_sel ; LDT so don't bother
  839. cmp CountFreeSel, 256
  840. jae got_either_sel
  841. lsl bx, gdtdsc ; LDT already full size?
  842. cmp bx, 0F000h
  843. ja got_either_sel
  844. push ax
  845. push cx
  846. mov cx, 256
  847. DPMICALL 0000h
  848. jc gs_after_free
  849. mov bx, ax
  850. gs_free_it:
  851. cCall free_sel,<bx> ; Got the selectors, put them on
  852. lea bx, [bx+DSC_LEN] ; our free list the easy way...
  853. loop gs_free_it
  854. gs_after_free:
  855. pop cx
  856. pop ax
  857. endif; NOT WOW
  858. jmps got_either_sel
  859. got_dpmi_sel:
  860. SetKernelDS
  861. got_either_sel:
  862. cmp SelTableLen, 0
  863. je short gs_exit ; Not set yet
  864. push eax
  865. .ERRNZ DSC_LEN-8
  866. lea eax, [esi+ecx*DSC_LEN][-DSC_LEN] ; AX has last selector
  867. shr ax, 1 ; ignore high word...
  868. cmp ax, SelTableLen
  869. pop eax
  870. jb short gs_exit ; Can associate this selector
  871. if KDEBUG
  872. int 3
  873. endif
  874. mov bx, si
  875. xor si, si
  876. or bl, SEG_RING
  877. as_free:
  878. DPMICALL 0001h ; Free selector
  879. ; Give to WIN386 since we can't use it
  880. lea bx, [bx+DSC_LEN]
  881. loop as_free
  882. gs_exit:
  883. mov ds, gdtdsc
  884. UnSetKernelDS
  885. mov MySel, si
  886. popa
  887. mov si, MySel
  888. or si, si ; Set ZF for caller
  889. cEnd
  890. ;-----------------------------------------------------------------------;
  891. ; alloc_disc_data_sel
  892. ; alloc_data_sel
  893. ; alloc_data_sel32
  894. ; alloc_disc_CS_sel
  895. ; alloc_CS_sel
  896. ; alloc_NP_data_sel
  897. ; alloc_NP_CS_sel
  898. ;
  899. ; Set appropriate access rights flags then use
  900. ; alloc_sel to get a selector.
  901. ;
  902. ; Entry:
  903. ; Base address and Limit OR Owner
  904. ;
  905. ; Returns:
  906. ; Selector in AX
  907. ;
  908. ; Registers Destroyed:
  909. ; AX
  910. ;
  911. ; History:
  912. ; Fri 15-Jul-1988 21:05:19 -by- David N. Weise [davidw]
  913. ;
  914. ;-----------------------------------------------------------------------;
  915. assumes ds,nothing
  916. assumes es,nothing
  917. if ROM
  918. ;
  919. ; there is a bunch of selector allocating in the ROM initialization
  920. ; so have a couple functions for 16 bit limits...
  921. ;
  922. cProc far_alloc_data_sel16, <PUBLIC,FAR>
  923. parmD base
  924. parmW limit
  925. cBegin
  926. movzx eax, limit
  927. shl eax, 4
  928. mov edx, base
  929. cCall alloc_data_sel, <edx, eax>
  930. cEnd
  931. cProc alloc_data_sel16, <PUBLIC, NEAR>
  932. parmD base
  933. parmW limit
  934. cBegin
  935. movzx eax, limit
  936. shl eax, 4 ;; this is is paragraphs...
  937. mov edx, base
  938. cCall alloc_data_sel, <edx, eax>
  939. cEnd
  940. endif
  941. public alloc_data_sel32
  942. alloc_data_sel32 label near
  943. cProc alloc_data_sel,<PUBLIC,NEAR>
  944. ; parmD Address
  945. ; parmD Limit
  946. cBegin nogen
  947. mov ax,DSC_PRESENT+DSC_DATA
  948. jmps alloc_sel
  949. cEnd nogen
  950. ;-----------------------------------------------------------------------;
  951. ; alloc_sel ;
  952. ; ;
  953. ; Entry: ;
  954. ; AL = flags ;
  955. ; Returns: ;
  956. ; ;
  957. ; Error Returns: ;
  958. ; ;
  959. ; Registers Preserved: ;
  960. ; BX,CX,DX,DI,SI,DS,ES ;
  961. ; ;
  962. ; Registers Destroyed: ;
  963. ; ;
  964. ; Calls: ;
  965. ; ;
  966. ; History: ;
  967. ; ;
  968. ; Thu 07-Apr-1988 21:33:27 -by- David N. Weise [davidw] ;
  969. ; Added the GlobalNotify check. ;
  970. ; ;
  971. ; Sun Feb 01, 1987 07:48:39p -by- David N. Weise [davidw] ;
  972. ; Added this nifty comment block. ;
  973. ;-----------------------------------------------------------------------;
  974. cProc alloc_sel,<PUBLIC,NEAR>,<bx,dx,si,di,ds,es>
  975. parmD Address
  976. parmD Limit
  977. localV DscBuf,DSC_LEN
  978. cBegin
  979. push ecx
  980. mov cx, 1
  981. test al, DSC_PRESENT
  982. jz short as_oneonly
  983. mov ecx, Limit ; Calculate how many selectors required
  984. cmp ecx, 100000h ; More than 1Mb?
  985. jb short as_byte
  986. add ecx, 0FFFh ; Round to 4K pages
  987. and cx, not 0FFFh
  988. mov Limit, ecx
  989. shr Limit, 12 ; # 4K pages
  990. or ah, DSC_GRANULARITY ; 4K granularity!
  991. as_byte:
  992. dec Limit ; Came in as length, now limit
  993. add ecx, 0FFFFh
  994. shr ecx, 16 ; # selectors in array
  995. as_oneonly:
  996. call get_sel
  997. jz short a_s_exit ; No selectors left
  998. mov bx, si ; Selector in bx for DPMI
  999. or bl, SEL_LDT
  1000. lea di, DscBuf
  1001. smov es, ss ; es:di points to descriptor buffer
  1002. test al, DSC_PRESENT
  1003. jnz short set_everything
  1004. push ax
  1005. if ROM
  1006. SetKernelDS
  1007. mov ds, gdtdsc
  1008. assumes ds,nothing
  1009. else
  1010. mov ds, gdtdsc
  1011. endif
  1012. and bl, not 7
  1013. pop word ptr [bx].dsc_access
  1014. mov ax, word ptr Limit
  1015. mov [bx].dsc_limit, ax
  1016. mov [bx].dsc_hbase, cl ; Number of selectors here
  1017. ifdef WOW
  1018. smov es, ds ; es:di -> descriptor
  1019. mov di, bx
  1020. or bl, SEG_RING ; bx selector #
  1021. DPMICALL 000Ch ; Set descriptor
  1022. endif; WOW
  1023. jmps as_done
  1024. set_everything:
  1025. and ah, not 0Fh ; Zero limit 19:16
  1026. or ah, byte ptr Limit+2 ; Fill in limit 19:16
  1027. mov word ptr DscBuf.dsc_access, ax
  1028. mov ax, Limit.lo
  1029. mov DscBuf.dsc_limit, ax
  1030. mov ax, Address.lo
  1031. mov DscBuf.dsc_lbase, ax
  1032. mov ax, Address.hi
  1033. mov DscBuf.dsc_mbase, al
  1034. mov DscBuf.dsc_hbase, ah
  1035. call fill_in_selector_array
  1036. as_done:
  1037. or si, SEG_RING
  1038. a_s_exit:
  1039. mov ax, si
  1040. pop ecx
  1041. cEnd
  1042. ;-----------------------------------------------------------------------;
  1043. ; free_sel ;
  1044. ; FreeSelector ;
  1045. ; ;
  1046. ; Entry: ;
  1047. ; ;
  1048. ; Returns: ;
  1049. ; ;
  1050. ; Error Returns: ;
  1051. ; ;
  1052. ; Registers Preserved: ;
  1053. ; AX,BX,CX,DX,DI,SI,DS,ES ;
  1054. ; ;
  1055. ; Registers Destroyed: ;
  1056. ; ;
  1057. ; Calls: ;
  1058. ; ;
  1059. ; History: ;
  1060. ; ;
  1061. ;-----------------------------------------------------------------------;
  1062. assumes ds,nothing
  1063. assumes es,nothing
  1064. cProc IFreeSelector,<FAR,PUBLIC>
  1065. parmW selector
  1066. cBegin
  1067. xor ax, ax
  1068. mov es, ax
  1069. cCall FreeSelArray,<selector>
  1070. cEnd
  1071. assumes ds, nothing
  1072. assumes es, nothing
  1073. ifdef WOW
  1074. ; save cx too.
  1075. cProc free_sel,<PUBLIC,NEAR>,<ax,bx,si,ds,cx>
  1076. else
  1077. cProc free_sel,<PUBLIC,NEAR>,<ax,bx,si,ds>
  1078. endif
  1079. parmW selector
  1080. cBegin
  1081. pushf ; !!! for the nonce
  1082. mov bx,selector ; must be careful in gcompact
  1083. ; to ignore error return
  1084. call SetKernelDSProc ; Must call direct in this file
  1085. ReSetKernelDS
  1086. if ROM
  1087. ; don't free ROM selectors...
  1088. cmp bx, sel1stAvail
  1089. jb sel_freed
  1090. endif
  1091. cmp gdtdsc, 0
  1092. je short give_to_win386
  1093. sel_check bx
  1094. mov si, bx
  1095. shr si, 1
  1096. cmp si, SelTableLen
  1097. if 0
  1098. mov si, SelTableLen
  1099. shl si, 1
  1100. cmp bx, si
  1101. endif
  1102. jae short give_to_win386
  1103. mov si, FirstFreeSel
  1104. inc CountFreeSel
  1105. mov ds, gdtdsc
  1106. UnSetKernelDS
  1107. ifdef WOW
  1108. mov cx, word ptr [bx+4]
  1109. endif
  1110. ; Link into list
  1111. mov ax, [si] ; ax := head.next
  1112. mov [si], bx ; head.next := new
  1113. mov [bx], ax ; new.next := ax
  1114. mov word ptr [bx][2], 0
  1115. mov dword ptr [bx][4], MY_SEL SHL 8 ; Make it free
  1116. ifdef WOW
  1117. cmp cx, MY_SEL
  1118. jz sel_freed
  1119. or bl, SEG_RING ; Ensure Table bit correct
  1120. mov cx, 1
  1121. DPMICALL WOW_DPMIFUNC_0C
  1122. endif
  1123. jmps sel_freed
  1124. give_to_win386:
  1125. or bl, SEG_RING ; Ensure Table bit correct
  1126. DPMICALL 0001H
  1127. sel_freed:
  1128. popf
  1129. cEnd
  1130. ;-----------------------------------------------------------------------;
  1131. ; FreeSelArray ;
  1132. ; ;
  1133. ; Entry: ;
  1134. ; ;
  1135. ; Returns: ;
  1136. ; ;
  1137. ; Error Returns: ;
  1138. ; ;
  1139. ; Registers Preserved: ;
  1140. ; AX,BX,CX,DX,DI,SI,DS,ES ;
  1141. ; ;
  1142. ; Registers Destroyed: ;
  1143. ; ;
  1144. ; Calls: ;
  1145. ; ;
  1146. ; History: ;
  1147. ; ;
  1148. ;-----------------------------------------------------------------------;
  1149. assumes ds,nothing
  1150. assumes es,nothing
  1151. cProc FreeSelArray,<PUBLIC,NEAR>,<ax,bx>
  1152. parmW selector
  1153. cBegin
  1154. push ecx
  1155. mov cx, 1 ; In case lar, lsl fail, one sel to free
  1156. mov bx, selector
  1157. Handle_To_Sel bl
  1158. ifdef WOW
  1159. if KDEBUG
  1160. push ds
  1161. SetKernelDS
  1162. cmp DemandLoadSel, 0 ; Skip the test if we're freeing DemandLoadSel
  1163. UnSetKernelDS
  1164. pop ds
  1165. je short fsa_no_test
  1166. push bx
  1167. push ds
  1168. mov ds, gdtdsc
  1169. and bl, not 7
  1170. mov ch, [bx].dsc_access
  1171. pop ds
  1172. pop bx
  1173. lar ax, bx
  1174. and ah, 0feh ;ignore access bit
  1175. and ch, 0feh ;ignore access bit
  1176. cmp ah, ch
  1177. je short LDTs_match
  1178. kerror 0, <System LDT does not match Shadow LDT>
  1179. LDTs_match:
  1180. xor ch, ch
  1181. fsa_no_test:
  1182. endif
  1183. endif
  1184. lar ax, bx
  1185. jnz short just_free_it ; I'm completely confused...
  1186. test ah, DSC_CODEDATA ; Code or data?
  1187. jz short just_free_it ; No, assume only one selector
  1188. test ah, DSC_PRESENT ; Present?
  1189. jnz short use_limit ; yes, calculate # sels from limit
  1190. ifdef WOW
  1191. ; MarkSelNotPresent Saves Number of selectors in the dsc_hbase entry to get
  1192. ; it back directly from our copy of the LDT.
  1193. push bx
  1194. push ds
  1195. mov ds, gdtdsc
  1196. and bl, not 7
  1197. xor cx,cx
  1198. mov cl,[bx].dsc_hbase ; Get Saved # selectors
  1199. pop ds
  1200. pop bx
  1201. else
  1202. push dx ; DPMI call 6 returns CX:DX
  1203. DPMICALL 0006h ; Get physical address
  1204. shr cx, 8 ; number of selectors
  1205. pop dx
  1206. endif; WOW
  1207. jmps just_free_it
  1208. use_limit:
  1209. lsl ecx, ebx
  1210. jnz short just_free_it ; Not present
  1211. Limit_To_Selectors ecx
  1212. just_free_it:
  1213. if KDEBUG
  1214. cmp cl,ch
  1215. jnz short skip_zero_inc
  1216. kerror 0, <Looping on cx=0 in FreeSelArray>
  1217. inc cl
  1218. skip_zero_inc:
  1219. endif
  1220. just_free_it2:
  1221. cCall free_sel,<bx> ; (preserves cx)
  1222. lea bx, [bx+DSC_LEN]
  1223. loop just_free_it2 ; Any left to free
  1224. pop ecx
  1225. cEnd
  1226. ;-----------------------------------------------------------------------;
  1227. ; GrowSelArray ;
  1228. ; ;
  1229. ; Entry: ;
  1230. ; ;
  1231. ; Returns: ;
  1232. ; ;
  1233. ; Error Returns: ;
  1234. ; AX = 0 ;
  1235. ; ZF = 1 ;
  1236. ; ;
  1237. ; Registers Preserved: ;
  1238. ; AX,BX,CX,DX,DI,SI,DS,ES ;
  1239. ; ;
  1240. ; Registers Destroyed: ;
  1241. ; ;
  1242. ; Calls: ;
  1243. ; ;
  1244. ; History: ;
  1245. ; ;
  1246. ;-----------------------------------------------------------------------;
  1247. assumes ds,nothing
  1248. assumes es,nothing
  1249. cProc GrowSelArray,<PUBLIC,NEAR>,<bx,di>
  1250. localV DscBuf,DSC_LEN
  1251. cBegin
  1252. push ecx
  1253. mov di, ds:[esi].pga_handle
  1254. mov bx, di
  1255. Handle_To_Sel di
  1256. lsl eax, edi
  1257. Limit_To_Selectors eax
  1258. if KDEBUG
  1259. cmp al, ds:[esi].pga_selcount
  1260. je short gsa_count_ok
  1261. int 3
  1262. int 3
  1263. gsa_count_ok:
  1264. endif
  1265. mov ecx, edx ; New size
  1266. add ecx, 0FFFFh
  1267. shr ecx, 16 ; new # selectors
  1268. cmp ax, cx ; Same # of selectors required?
  1269. je short gsa_done ; yes, just return!
  1270. push si
  1271. push es
  1272. push ds
  1273. push di ; Argument to FreeSelArray
  1274. cmp cx, 255 ; Max array is 255.
  1275. jae short gsa_nosels
  1276. call get_sel ; get a new selector array
  1277. jz short gsa_nosels
  1278. push bx
  1279. mov bx, di ; DI had original selector
  1280. push ds
  1281. if ROM
  1282. SetKernelDS
  1283. mov es,gdtdsc
  1284. mov ds,gdtdsc
  1285. assumes ds,nothing
  1286. else
  1287. mov ds,gdtdsc
  1288. mov es,gdtdsc
  1289. endif
  1290. push si
  1291. mov di,si
  1292. and di, not 7
  1293. mov si,bx
  1294. and si, not 7
  1295. MovsDsc
  1296. pop si
  1297. pop ds
  1298. ifdef WOW
  1299. push cx
  1300. push bx
  1301. mov cx, 1
  1302. mov bx, si
  1303. or bx, SEG_RING_MASK
  1304. DPMICALL WOW_DPMIFUNC_0C
  1305. pop bx
  1306. pop cx
  1307. endif
  1308. mov di, si ; New selector in DI
  1309. pop bx
  1310. pop si
  1311. pop ds
  1312. cCall AssociateSelector32,<si,0,0>
  1313. pop es
  1314. pop si
  1315. mov ax, bx
  1316. and ax, SEG_RING_MASK ; Ring bits
  1317. or ax, di ; New handle
  1318. mov ds:[esi].pga_handle, ax
  1319. mov ds:[esi].pga_selcount, cl
  1320. cCall AssociateSelector32,<ax,esi>
  1321. jmps gsa_done
  1322. gsa_nosels:
  1323. pop di
  1324. pop ds
  1325. pop es
  1326. pop si
  1327. xor ax, ax ; Indicate failure
  1328. jmps gsa_ret
  1329. gsa_done:
  1330. mov ax, ds:[esi].pga_handle
  1331. or ax, ax ; Success
  1332. gsa_ret:
  1333. pop ecx
  1334. cEnd
  1335. ;=======================================================================;
  1336. ; ;
  1337. ; SELECTOR ALIAS ROUTINES ;
  1338. ; ;
  1339. ;=======================================================================;
  1340. ;-----------------------------------------------------------------------;
  1341. ; PrestoChangoSel
  1342. ;
  1343. ;
  1344. ; Entry:
  1345. ;
  1346. ; Returns:
  1347. ;
  1348. ; Registers Destroyed:
  1349. ;
  1350. ; History:
  1351. ; Thu 08-Dec-1988 14:17:38 -by- David N. Weise [davidw]
  1352. ; Wrote it!
  1353. ;-----------------------------------------------------------------------;
  1354. assumes ds,nothing
  1355. assumes es,nothing
  1356. cProc IPrestoChangoSelector,<PUBLIC,FAR>,<di,si>
  1357. parmW sourcesel
  1358. parmW destsel
  1359. localV DscBuf,DSC_LEN
  1360. cBegin
  1361. ifdef WOW
  1362. smov es, ss
  1363. lea di, DscBuf
  1364. mov bx, sourcesel
  1365. DPMICALL 000Bh ; LATER change this to a single
  1366. xor DscBuf.dsc_access, DSC_CODE_BIT ; DPMI call, read from gdtdsc
  1367. mov bx, destsel
  1368. DPMICALL 000Ch
  1369. mov ax, bx
  1370. else
  1371. push bx
  1372. push ds
  1373. if ROM
  1374. SetKernelDS
  1375. mov es, gdtdsc
  1376. mov ds, gdtdsc
  1377. assumes ds, nothing
  1378. else
  1379. mov ds, gdtdsc
  1380. mov es, gdtdsc
  1381. endif
  1382. mov si, sourcesel
  1383. and si, not 7
  1384. mov di, destsel
  1385. and di, not 7
  1386. MovsDsc
  1387. lea bx,[di-DSC_LEN]
  1388. xor ds:[bx].dsc_access,DSC_CODE_BIT ; Toggle CODE/DATA
  1389. pop ds
  1390. or bl, SEG_RING
  1391. mov ax, bx
  1392. pop bx
  1393. endif; WOW
  1394. smov es,0
  1395. cEnd
  1396. ;-----------------------------------------------------------------------;
  1397. ; AllocAlias ;
  1398. ; AllocCStoDSAlias ;
  1399. ; AllocDStoCSAlias ;
  1400. ; All these routines return an alias selector for the ;
  1401. ; given selector. ;
  1402. ; ;
  1403. ; Entry: ;
  1404. ; ;
  1405. ; Returns: ;
  1406. ; AX is alias selector ;
  1407. ; DX is original selector (compatibility thing) ;
  1408. ; ;
  1409. ; Error Returns: ;
  1410. ; ;
  1411. ; Registers Preserved: ;
  1412. ; BX,CX,DI,SI,DS ;
  1413. ; ;
  1414. ; Registers Destroyed: ;
  1415. ; ES destroyed ;
  1416. ; ;
  1417. ; Calls: ;
  1418. ; ;
  1419. ; History: ;
  1420. ; ;
  1421. ;-----------------------------------------------------------------------;
  1422. assumes ds,nothing
  1423. assumes es,nothing
  1424. labelFP <PUBLIC,IAllocDStoCSAlias>
  1425. ;** AllocDStoCSAlias has an interesting hack. A fix was made to
  1426. ;** not allow apps to GlobalAlloc fixed memory. This was done
  1427. ;** for performance reasons. The only reason we can ascertain
  1428. ;** for an app needing fixed GlobalAlloc'ed memory is in the case
  1429. ;** of alias selectors. We assume that all apps needing alias
  1430. ;** selectors will use this function to make the alias. So, if
  1431. ;** we see a DStoCS alias being made, we make sure the DS is fixed.
  1432. push bp
  1433. mov bp, sp ;Create the stack frame
  1434. push WORD PTR [bp + 6] ;Get handle/selector
  1435. IF KDEBUG
  1436. call GlobalHandleNorip ;Make sure it's really a handle
  1437. ELSE
  1438. call IGlobalHandle ;Make sure it's really a handle
  1439. ENDIF
  1440. test ax, 1 ;Fixed blocks have low bit set
  1441. jnz SHORT ADCA_Already_Fixed ;It's already a fixed block!
  1442. ;** If the block is not fixed, it may be locked so we must check this.
  1443. push ax ;Save returned selector
  1444. push ax ;Use as parameter
  1445. call IGlobalFlags ;Returns lock count if any
  1446. or al, al ;Non-zero lock count?
  1447. pop ax ;Get selector back
  1448. jnz SHORT ADCA_Already_Fixed ;Yes, don't mess with it
  1449. ;** Fix the memory. Note that we're only doing this for the
  1450. ;** apps that are calling this on non-fixed or -locked memory.
  1451. ;** This will cause them to rip on the GlobalFree call to this
  1452. ;** memory, but at least it won't move on them!
  1453. push ax ;Fix it
  1454. call IGlobalFix
  1455. ADCA_Already_Fixed:
  1456. pop bp ;Clear our stack frame
  1457. ;** Flag which type of alias to make and jump to common routine
  1458. mov dl, 1
  1459. jmps aka
  1460. labelFP <PUBLIC,IAllocCStoDSAlias>
  1461. xor dl, dl
  1462. cProc aka,<FAR,PUBLIC>, <bx,cx,si,di,ds>
  1463. parmW sourceSel
  1464. localV DscBuf,DSC_LEN
  1465. localB flag ; 0 for data, !0 for code
  1466. cBegin
  1467. mov flag, dl
  1468. mov cx, 1
  1469. call get_sel
  1470. mov ax, si ; in case it failed
  1471. jz short aka_nope
  1472. or si, SEG_RING
  1473. ifdef WOW ; LATER Single DPMI call
  1474. push si ; save Target Selector
  1475. smov es,ss
  1476. lea di,DscBuf
  1477. mov bx,sourceSel
  1478. DPMICALL 000Bh ; Read the Selector into DscBuf
  1479. and es:[di].dsc_access,NOT DSC_CODE_BIT ; Toggle CODE/DATA
  1480. cmp flag, 0
  1481. jz @F
  1482. or es:[di].dsc_access,DSC_CODE_BIT
  1483. @@:
  1484. pop bx ; restore Target Selector
  1485. DPMICALL 0000Ch
  1486. else
  1487. if ROM
  1488. SetKernelDS
  1489. mov es, gdtdsc
  1490. mov ds, gdtdsc
  1491. assumes ds, nothing
  1492. else
  1493. mov ds, gdtdsc
  1494. mov es, gdtdsc
  1495. endif
  1496. mov bx, si
  1497. mov di, si
  1498. and di, not 7
  1499. mov si, sourceSel
  1500. and si, not 7
  1501. MovsDsc
  1502. and es:[di][-DSC_LEN].dsc_access,NOT DSC_CODE_BIT ; Toggle CODE/DATA
  1503. cmp flag, 0
  1504. jz @F
  1505. or es:[di][-DSC_LEN].dsc_access,DSC_CODE_BIT
  1506. @@:
  1507. endif; WOW
  1508. mov ax, bx
  1509. smov es,0
  1510. aka_nope:
  1511. mov dx,sourceSel
  1512. cEnd
  1513. cProc AllocAlias,<FAR,PUBLIC>, <bx,cx,si,di,ds>
  1514. parmW selector
  1515. cBegin
  1516. ifdef WOW
  1517. push bx ; Whitewater tool ObjDraw needs this too
  1518. endif
  1519. mov cx, 1
  1520. call get_sel
  1521. jz short aca_nope
  1522. or si, SEG_RING
  1523. cCall IPrestoChangoSelector,<selector,si>
  1524. aca_nope:
  1525. ; WhiteWater Resource Toolkit (shipped with Borland's Turbo
  1526. ; Pascal) depends on dx being the data selector which was true
  1527. ; in 3.0 but in 3.1 validation layer destroys it.
  1528. mov dx,selector
  1529. ifdef WOW
  1530. pop bx
  1531. endif
  1532. cEnd
  1533. ;=======================================================================;
  1534. ; ;
  1535. ; SELECTOR MANPULATION ROUTINES ;
  1536. ; ;
  1537. ;=======================================================================;
  1538. ;-----------------------------------------------------------------------;
  1539. ; fill_in_selector_array ;
  1540. ; ;
  1541. ; Entry: ;
  1542. ; AX = Limit for object ;
  1543. ; DH = Discard bit for descriptors ;
  1544. ; DL = Access bits ;
  1545. ; BX:DI = 32 bit base address of object ;
  1546. ; SI = index into LDT ;
  1547. ; Returns: ;
  1548. ; ;
  1549. ; Error Returns: ;
  1550. ; ;
  1551. ; Registers Preserved: ;
  1552. ; SI, DI, DS, ES ;
  1553. ; ;
  1554. ; Registers Destroyed: ;
  1555. ; AX,BX,CX,DX ;
  1556. ; ;
  1557. ; Calls: ;
  1558. ; ;
  1559. ; History: ;
  1560. ; ;
  1561. ;-----------------------------------------------------------------------;
  1562. cProc fill_in_selector_array,<PUBLIC,NEAR>
  1563. cBegin nogen
  1564. push ds
  1565. mov ds, gdtdsc
  1566. push bx
  1567. push cx
  1568. mov dh, es:[di].dsc_hlimit ; For granularity
  1569. next_sel:
  1570. ;; DPMICALL 000Ch ; Set this descriptor
  1571. push bx ; Set Descriptor
  1572. and bl, not 7
  1573. mov ax, es:[di] ; This looks slow but it isn't...
  1574. mov ds:[bx], ax
  1575. mov ax, es:[di][2]
  1576. mov ds:[bx][2], ax
  1577. mov ax, es:[di][4]
  1578. mov ds:[bx][4], ax
  1579. mov ax, es:[di][6]
  1580. mov ds:[bx][6], ax
  1581. pop bx
  1582. lea bx, [bx+DSC_LEN] ; On to next selector
  1583. add es:[di].dsc_mbase, 1 ; Add 64kb to address
  1584. adc es:[di].dsc_hbase, 0
  1585. test dh, DSC_GRANULARITY ; Page granular?
  1586. jz short byte_granular
  1587. sub es:[di].dsc_limit, 16 ; 64K is 16 4K pages
  1588. sbb es:[di].dsc_hlimit, 0 ; Carry into hlimit
  1589. loop next_sel
  1590. jmps fisa_ret
  1591. byte_granular:
  1592. dec es:[di].dsc_hlimit ; subtract 64kb from limit
  1593. loop next_sel
  1594. fisa_ret:
  1595. pop cx
  1596. pop bx
  1597. DPMICALL WOW_DPMIFUNC_0C
  1598. pop ds
  1599. ret
  1600. cEnd nogen
  1601. ;-----------------------------------------------------------------------;
  1602. ; GetSelectorBase
  1603. ; get_physical_address
  1604. ;
  1605. ;
  1606. ; Entry:
  1607. ;
  1608. ; Returns:
  1609. ; DX:AX 32 bit physical address
  1610. ; Registers Destroyed:
  1611. ;
  1612. ; History:
  1613. ; Sat 09-Jul-1988 16:40:59 -by- David N. Weise [davidw]
  1614. ;
  1615. ;-----------------------------------------------------------------------;
  1616. assumes ds,nothing
  1617. assumes es,nothing
  1618. cProc GetSelectorBase,<PUBLIC,FAR>
  1619. parmW selector
  1620. cBegin
  1621. cCall get_physical_address, <selector>
  1622. cEnd
  1623. cProc get_physical_address,<PUBLIC,NEAR>
  1624. parmW selector
  1625. cBegin
  1626. push bx
  1627. push cx
  1628. mov bx, selector
  1629. push ds ; Get Segment Base Address
  1630. if ROM
  1631. SetKernelDS
  1632. mov ds, gdtdsc
  1633. assumes ds, nothing
  1634. else
  1635. mov ds, gdtdsc
  1636. endif
  1637. and bl, not 7
  1638. mov ax, ds:[bx].dsc_lbase
  1639. mov dl, ds:[bx].dsc_mbase
  1640. mov dh, ds:[bx].dsc_hbase
  1641. pop ds
  1642. pop cx
  1643. pop bx
  1644. cEnd
  1645. ;-----------------------------------------------------------------------;
  1646. ; get_selector_length16
  1647. ;
  1648. ;
  1649. ; Entry:
  1650. ;
  1651. ; Returns:
  1652. ; AX 16 bit segment length
  1653. ; Registers Destroyed:
  1654. ;
  1655. ; History:
  1656. ; Sat 09-Jul-1988 16:40:59 -by- David N. Weise [davidw]
  1657. ;
  1658. ;-----------------------------------------------------------------------;
  1659. assumes ds,nothing
  1660. assumes es,nothing
  1661. cProc get_selector_length16,<PUBLIC,NEAR>
  1662. parmW selector
  1663. cBegin
  1664. mov ax, -1
  1665. lsl ax, selector
  1666. inc ax ; length is one bigger!
  1667. cEnd
  1668. ;-----------------------------------------------------------------------;
  1669. ; set_physical_address
  1670. ;
  1671. ;
  1672. ; Entry:
  1673. ; DX:AX 32 bit physical address
  1674. ; Returns:
  1675. ;
  1676. ; Registers Destroyed:
  1677. ;
  1678. ; History:
  1679. ; Sat 09-Jul-1988 16:40:59 -by- David N. Weise [davidw]
  1680. ;
  1681. ;-----------------------------------------------------------------------;
  1682. assumes ds,nothing
  1683. assumes es,nothing
  1684. cProc far_set_physical_address,<PUBLIC,FAR>
  1685. parmW selector
  1686. cBegin
  1687. cCall set_physical_address,<selector>
  1688. cEnd
  1689. cProc set_physical_address,<PUBLIC,NEAR>,<bx,di>
  1690. parmW selector
  1691. cBegin
  1692. push ecx
  1693. mov bx, selector
  1694. CheckLDT bl
  1695. lsl ecx, ebx
  1696. if KDEBUG
  1697. jz short spa_ok
  1698. int 3
  1699. spa_ok:
  1700. endif
  1701. Limit_To_Selectors ecx
  1702. mov di, cx
  1703. mov cx, dx ; CX:DX has new address
  1704. mov dx, ax
  1705. push ds
  1706. push bx
  1707. if ROM
  1708. SetKernelDS
  1709. mov ds, gdtdsc
  1710. assumes ds, nothing
  1711. else
  1712. ifdef WOW
  1713. set_bases:
  1714. DPMICALL 0007h ; Set selector base
  1715. else
  1716. mov ds, gdtdsc
  1717. set_bases:
  1718. and bl, not 7
  1719. mov ds:[bx].dsc_lbase, dx
  1720. mov ds:[bx].dsc_mbase, cl
  1721. mov ds:[bx].dsc_hbase, ch
  1722. endif; WOW
  1723. lea bx, [bx+DSC_LEN] ; On to next selector
  1724. inc cx ; Add 64k to base
  1725. dec di
  1726. jnz set_bases
  1727. pop bx
  1728. pop ds
  1729. endif; ROM
  1730. mov ax, dx ; Restore AX and DX
  1731. mov dx, cx
  1732. pop ecx
  1733. cEnd
  1734. ;-----------------------------------------------------------------------;
  1735. ; set_selector_address32
  1736. ;
  1737. ;
  1738. ; Entry:
  1739. ;
  1740. ; Returns:
  1741. ;
  1742. ; Registers Destroyed:
  1743. ;
  1744. ; History:
  1745. ; Sat 09-Jul-1988 16:40:59 -by- David N. Weise [davidw]
  1746. ;
  1747. ;-----------------------------------------------------------------------;
  1748. assumes ds,nothing
  1749. assumes es,nothing
  1750. cProc set_selector_address32,<PUBLIC,NEAR>,<ax,dx>
  1751. parmW selector
  1752. parmD addr
  1753. cBegin
  1754. mov dx, addr.sel
  1755. mov ax, addr.off
  1756. cCall set_physical_address,<selector>
  1757. cEnd
  1758. ;-----------------------------------------------------------------------;
  1759. ; set_sel_limit
  1760. ;
  1761. ;
  1762. ; Entry:
  1763. ; CX:BX = length of segment
  1764. ; Returns:
  1765. ;
  1766. ; Registers Destroyed:
  1767. ; CX
  1768. ;
  1769. ; History:
  1770. ; Fri 15-Jul-1988 19:41:44 -by- David N. Weise [davidw]
  1771. ;
  1772. ;-----------------------------------------------------------------------;
  1773. assumes ds,nothing
  1774. assumes es,nothing
  1775. cProc set_sel_limit,<PUBLIC,NEAR>,<ax,dx,si,di,es,ds>
  1776. parmW selector
  1777. localV DscBuf,DSC_LEN
  1778. cBegin
  1779. push ebx
  1780. push ecx
  1781. push bx ; Get existing descriptor
  1782. smov es, ss
  1783. lea di, DscBuf
  1784. mov bx, selector
  1785. push ds ; Get Descriptor
  1786. if ROM
  1787. SetKernelDS
  1788. mov ds, gdtdsc
  1789. assumes ds,nothing
  1790. else
  1791. mov ds, gdtdsc
  1792. endif
  1793. push si
  1794. mov si, bx
  1795. and si, not 7
  1796. MovsDsc
  1797. lea di, [di-DSC_LEN] ; Restore DI
  1798. pop si
  1799. pop ds
  1800. pop bx
  1801. mov dx, word ptr [DscBuf.dsc_access]
  1802. and dh, 0F0h ; Zap hlimit bits
  1803. test dl, DSC_PRESENT
  1804. jz short ssl_set_limit1 ; Not present, just one to set
  1805. and dh, NOT DSC_GRANULARITY ; Byte granularity
  1806. shl ecx, 16
  1807. mov cx, bx ; DWORD length
  1808. mov ebx, ecx
  1809. cmp ecx, 100000h ; More than 1Mb?
  1810. jb short ssl_byte
  1811. add ecx, 0FFFh ; Round to 4k pages
  1812. and cx, not 0FFFh
  1813. mov ebx, ecx
  1814. shr ebx, 12 ; # 4k pages
  1815. or dh, DSC_GRANULARITY ; Set 4k granularity
  1816. ssl_byte:
  1817. add ecx, 0FFFFh
  1818. shr ecx, 16 ; # selectors in array
  1819. cmp cx, 1
  1820. je short ssl_set_limit1
  1821. dec ebx ; length to limit
  1822. mov ax, bx ; low 16 bits of limit
  1823. shr ebx, 16
  1824. or dh, bl ; Bits 19:16 of limit
  1825. mov word ptr DscBuf.dsc_access, dx
  1826. mov DscBuf.dsc_limit, ax
  1827. mov bx, Selector
  1828. call fill_in_selector_array
  1829. jmps ssl_done
  1830. ssl_set_limit1: ; Fast out for one only
  1831. dec bx ; Came in as length
  1832. mov DscBuf.dsc_limit, bx ; and limit
  1833. mov word ptr DscBuf.dsc_access, dx ; Access, Discard and hlimit
  1834. mov bx, Selector
  1835. DPMICALL 000Ch
  1836. ssl_done:
  1837. smov ss,ss ; It may be SS we're changing
  1838. pop ecx
  1839. pop ebx
  1840. cEnd
  1841. ;-----------------------------------------------------------------------;
  1842. ; set_selector_limit32
  1843. ;
  1844. ;
  1845. ; Entry:
  1846. ;
  1847. ; Returns:
  1848. ;
  1849. ; Registers Destroyed:
  1850. ;
  1851. ; History:
  1852. ; Fri 15-Jul-1988 19:41:44 -by- David N. Weise [davidw]
  1853. ;
  1854. ;-----------------------------------------------------------------------;
  1855. assumes ds,nothing
  1856. assumes es,nothing
  1857. cProc set_selector_limit32,<PUBLIC,NEAR>,<cx,bx>
  1858. parmW selector
  1859. parmD sel_len
  1860. cBegin
  1861. mov cx, sel_len.hi
  1862. mov bx, sel_len.lo
  1863. cCall set_sel_limit,<selector>
  1864. cEnd
  1865. ;-----------------------------------------------------------------------;
  1866. ; mark_sel_NP
  1867. ;
  1868. ;
  1869. ; Entry:
  1870. ;
  1871. ; Returns:
  1872. ;
  1873. ; Registers Destroyed:
  1874. ; BX
  1875. ;
  1876. ; History:
  1877. ; Fri 15-Jul-1988 21:37:22 -by- David N. Weise [davidw]
  1878. ;
  1879. ;-----------------------------------------------------------------------;
  1880. assumes ds,nothing
  1881. assumes es,nothing
  1882. cProc mark_sel_NP,<PUBLIC,NEAR>,<ds>
  1883. parmW selector
  1884. parmW owner
  1885. localV DscBuf,DSC_LEN
  1886. cBegin
  1887. push ecx
  1888. mov bx, selector
  1889. Handle_To_Sel bl
  1890. lsl ecx, ebx ; How many selectors do we have now?
  1891. Limit_To_Selectors ecx
  1892. push ax
  1893. push es
  1894. push di
  1895. push ds
  1896. if ROM
  1897. SetKernelDS
  1898. mov ds, gdtdsc
  1899. assumes ds, nothing
  1900. else
  1901. mov ds, gdtdsc
  1902. endif
  1903. push bx
  1904. and bl, not 7
  1905. mov [bx].dsc_hbase, cl ; Save # selectors
  1906. mov [bx].dsc_hlimit, DSC_DISCARDABLE
  1907. and [bx].dsc_access, NOT DSC_PRESENT
  1908. mov cx, owner
  1909. mov [bx].dsc_owner, cx ; Set owner in descriptor
  1910. ifdef WOW
  1911. ;
  1912. ; Now the copy of the LDT has the correct info set VIA DPMI the real NT
  1913. ; LDT Entry
  1914. smov es,ds
  1915. mov di,bx ; es:di->selector
  1916. or bx, SEG_RING ; BX = selector
  1917. DPMICALL 000Ch
  1918. endif; WOW
  1919. pop bx
  1920. pop ds
  1921. SetKernelDS
  1922. mov ds, pGlobalHeap
  1923. UnSetKernelDS
  1924. cCall AssociateSelector32,<bx,0,cx> ; Save owner in selector table
  1925. pop di
  1926. pop es
  1927. pop ax
  1928. pop ecx
  1929. cEnd
  1930. ;-----------------------------------------------------------------------;
  1931. ; mark_sel_PRESENT
  1932. ;
  1933. ;
  1934. ; Entry:
  1935. ;
  1936. ; Returns:
  1937. ;
  1938. ; Registers Destroyed:
  1939. ;
  1940. ; History:
  1941. ; Fri 15-Jul-1988 21:37:22 -by- David N. Weise [davidw]
  1942. ;
  1943. ;-----------------------------------------------------------------------;
  1944. assumes ds,nothing
  1945. assumes es,nothing
  1946. cProc mark_sel_PRESENT,<PUBLIC,NEAR>,<dx,di,es>
  1947. parmD arena_ptr
  1948. parmW selector
  1949. localV DscBuf,DSC_LEN
  1950. cBegin
  1951. push eax
  1952. push ebx
  1953. push ecx
  1954. smov es, ss
  1955. lea di, DscBuf
  1956. mov bx, selector
  1957. DPMICALL 000Bh ; Get existing descriptor
  1958. mov ax, word ptr DscBuf.dsc_access ; Access and hlimit
  1959. or al, DSC_PRESENT ; Mark it present
  1960. and ah, NOT DSC_GRANULARITY ; Assume byte granular
  1961. mov esi, arena_ptr
  1962. CheckDS
  1963. mov ecx, ds:[esi].pga_size
  1964. mov ebx, ecx
  1965. cmp ecx, 100000h ; New size more than 1Mb?
  1966. jb short msp_byte
  1967. add ebx, 0FFFh ; Round to 4k pages
  1968. and bx, not 0FFFh
  1969. shr ebx, 12 ; # 4k pages
  1970. or ah, DSC_GRANULARITY ; Set 4k granularity
  1971. msp_byte:
  1972. dec ebx
  1973. mov DscBuf.dsc_limit, bx ; Fill in new limit fields
  1974. shr ebx, 16
  1975. and bl, 0Fh
  1976. and ah, NOT 0Fh
  1977. or ah, bl
  1978. mov word ptr DscBuf.dsc_access, ax ; Fill in new hlimit and access
  1979. dec ecx
  1980. Limit_To_Selectors ecx ; New number of selectors
  1981. mov ds:[esi].pga_selcount, cl
  1982. mov bl, DscBuf.dsc_hbase ; Old number of selectors
  1983. sub bl, cl
  1984. je short go_ahead ; Same number, just fill in array
  1985. jb short get_big
  1986. ; here to get small
  1987. xor bh, bh
  1988. xchg bx, cx
  1989. shl bx, 3 ; Offset of first selector
  1990. .errnz DSC_LEN - 8
  1991. add bx, selector ; First selector to free
  1992. @@: cCall free_sel,<bx>
  1993. lea bx, [bx+DSC_LEN]
  1994. loop @B
  1995. jmps go_ahead ; And fill in remaining selectors
  1996. get_big:
  1997. mov ax, word ptr DscBuf.dsc_access ; Access bits in ax
  1998. mov ebx, ds:[esi].pga_address ; Get base address
  1999. mov ecx, ds:[esi].pga_size
  2000. cCall alloc_sel,<ebx,ecx> ; Access bits in ax
  2001. mov si, ax
  2002. or ax, ax ; did we get a set?
  2003. jz short return_new_handle
  2004. or si, SEG_RING ; Set ring bits like old selector
  2005. test selector, IS_SELECTOR
  2006. jnz short @F
  2007. StoH si
  2008. HtoS selector
  2009. @@:
  2010. cCall AssociateSelector32,<selector,0,0>
  2011. cCall FreeSelArray,<selector> ; Zap old handle
  2012. jmps return_new_handle
  2013. go_ahead:
  2014. mov ebx, ds:[esi].pga_address ; Fill in selector array with
  2015. mov DscBuf.dsc_lbase, bx ; new base and limit
  2016. shr ebx, 16
  2017. mov DscBuf.dsc_mbase, bl
  2018. mov DscBuf.dsc_hbase, bh
  2019. mov bx, selector
  2020. movzx cx, ds:[esi].pga_selcount
  2021. call fill_in_selector_array
  2022. mov si, selector ; return old selector in SI
  2023. return_new_handle:
  2024. pop ecx
  2025. pop ebx
  2026. pop eax
  2027. cEnd
  2028. ;-----------------------------------------------------------------------;
  2029. ; cmp_sel_address
  2030. ;
  2031. ; Compares the physical addresses corresponding to two selectors
  2032. ;
  2033. ; Entry:
  2034. ;
  2035. ; Returns:
  2036. ;
  2037. ; Registers Destroyed:
  2038. ;
  2039. ; History:
  2040. ; Sat 09-Jul-1988 19:10:14 -by- David N. Weise [davidw]
  2041. ;
  2042. ;-----------------------------------------------------------------------;
  2043. assumes ds,nothing
  2044. assumes es,nothing
  2045. cProc cmp_sel_address,<PUBLIC,NEAR>
  2046. parmW sel1
  2047. parmW sel2
  2048. cBegin
  2049. push ax
  2050. push ebx
  2051. push edx
  2052. cCall get_physical_address,<sel1>
  2053. mov bx, dx
  2054. shl ebx, 16
  2055. mov bx, ax ; First address in EBX
  2056. cCall get_physical_address,<sel2>
  2057. shl edx, 16
  2058. mov dx, ax ; Second address in EDX
  2059. cmp ebx, edx
  2060. pop edx
  2061. pop ebx
  2062. pop ax
  2063. ;;; mov ds,gdtdsc
  2064. ;;; mov si,sel1
  2065. ;;; mov di,sel2
  2066. ;;; sel_check si
  2067. ;;; sel_check di
  2068. ;;; mov al,[si].dsc_hbase
  2069. ;;; cmp al,[di].dsc_hbase
  2070. ;;; jne short csa_done
  2071. ;;; mov al,[si].dsc_mbase
  2072. ;;; cmp al,[di].dsc_mbase
  2073. ;;; jne short csa_done
  2074. ;;; mov ax,[si].dsc_lbase
  2075. ;;; cmp ax,[di].dsc_lbase
  2076. ;;;csa_done:
  2077. cEnd
  2078. ;-----------------------------------------------------------------------;
  2079. ; pdref ;
  2080. ; ;
  2081. ; Dereferences the given global handle, i.e. gives back abs. address. ;
  2082. ; ;
  2083. ; Arguments: ;
  2084. ; DX = selector ;
  2085. ; DS:DI = BURGERMASTER ;
  2086. ; ;
  2087. ; Returns: ;
  2088. ; ESI = address of arena header ;
  2089. ; AX = address of client data ;
  2090. ; CH = lock count or 0 for fixed objects ;
  2091. ; CL = flags ;
  2092. ; DX = handle, 0 for fixed objects ;
  2093. ; ;
  2094. ; Error Returns: ;
  2095. ; ZF = 1 if invalid or discarded ;
  2096. ; AX = 0 ;
  2097. ; BX = owner of discarded object ;
  2098. ; SI = handle of discarded object ;
  2099. ; ;
  2100. ; Registers Preserved: ;
  2101. ; ;
  2102. ; Registers Destroyed: ;
  2103. ; ;
  2104. ; Calls: ;
  2105. ; ;
  2106. ; History: ;
  2107. ; ;
  2108. ;-----------------------------------------------------------------------;
  2109. assumes ds,nothing
  2110. assumes es,nothing
  2111. cProc pdref,<PUBLIC,NEAR>
  2112. cBegin nogen
  2113. mov si, dx
  2114. sel_check si
  2115. or si, si ; Null handle?
  2116. mov ax, si
  2117. jz short pd_exit ; yes, return 0
  2118. lar eax, edx
  2119. jnz short pd_totally_bogus
  2120. shr eax, 8
  2121. ; We should beef up the check for a valid discarded sel.
  2122. xor cx,cx
  2123. test ah, DSC_DISCARDABLE
  2124. jz short pd_not_discardable
  2125. or cl, GA_DISCARDABLE
  2126. ; Discardable, is it code?
  2127. test al, DSC_CODE_BIT
  2128. jz short pd_not_code
  2129. or cl,GA_DISCCODE
  2130. pd_not_code:
  2131. pd_not_discardable:
  2132. test al, DSC_PRESENT
  2133. jnz short pd_not_discarded
  2134. ; object discarded
  2135. or cl,HE_DISCARDED
  2136. ifdef WOW
  2137. ; On WOW we don't copy the owner to the real LDT since it is slow to call
  2138. ; the NT Kernel, so we read our copy of it directly.
  2139. ; see set_discarded_sel_owner mattfe mar 23 93
  2140. move ax,es ; save es
  2141. mov bx,dx
  2142. mov es,cs:gdtdsc
  2143. and bl, not 7
  2144. mov bx,es:[bx].dsc_owner
  2145. mov es,ax ; restore
  2146. else
  2147. lsl bx, dx ; get the owner
  2148. endif
  2149. or si, SEG_RING-1 ; Handles are RING 2
  2150. xor ax,ax
  2151. jmps pd_exit
  2152. pd_not_discarded:
  2153. cCall get_arena_pointer32,<dx>
  2154. mov esi, eax
  2155. mov ax, dx
  2156. or esi, esi ; Unknown selector
  2157. jz short pd_maybe_alias
  2158. mov dx, ds:[esi].pga_handle
  2159. cmp dx, ax ; Quick check - handle in header
  2160. je short pd_match ; matches what we were given?
  2161. test al, IS_SELECTOR ; NOW, we MUST have been given
  2162. jz short pd_totally_bogus ; a selector address.
  2163. push ax
  2164. StoH al ; Turn into handle
  2165. cmp dx, ax
  2166. pop ax
  2167. jne short pd_nomatch
  2168. pd_match:
  2169. or cl, ds:[esi].pga_flags
  2170. and cl, NOT HE_DISCARDED ; same as GA_NOTIFY!!
  2171. mov ax, dx ; Get address in AX
  2172. test dl, GA_FIXED ; DX contains handle
  2173. jnz short pd_fixed ; Does handle need derefencing?
  2174. mov ch, ds:[esi].pga_count
  2175. HtoS al ; Dereference moveable handle
  2176. jmps pd_exit
  2177. pd_totally_bogus:
  2178. xor ax,ax
  2179. pd_maybe_alias:
  2180. ife ROM
  2181. if KDEBUG
  2182. or dx,dx
  2183. jnz short dref_invalid
  2184. endif
  2185. endif
  2186. pd_nomatch: ; Handle did not match...
  2187. xor dx, dx
  2188. ;;; mov dx, ax ; Must be an alias...
  2189. pd_fixed:
  2190. ;;; xor si, si
  2191. ;;; xor dx, dx
  2192. pd_exit:
  2193. or ax,ax
  2194. ret
  2195. if KDEBUG
  2196. dref_invalid:
  2197. push ax
  2198. kerror ERR_GMEMHANDLE,<gdref: invalid handle>,0,dx
  2199. pop ax
  2200. jmps pd_nomatch
  2201. endif
  2202. cEnd nogen
  2203. cProc Far_pdref,<PUBLIC,FAR>
  2204. cBegin nogen
  2205. call pdref
  2206. ret
  2207. cEnd nogen
  2208. ;-----------------------------------------------------------------------;
  2209. ; get_rover_2 ;
  2210. ; ;
  2211. ; Entry: ;
  2212. ; ES Selector to get rover for ;
  2213. ; Returns: ;
  2214. ; ES (kr2dsc) is rover DATA and PRESENT ;
  2215. ; Error Returns: ;
  2216. ; ;
  2217. ; Registers Preserved: ;
  2218. ; AX,BX,CX,DX,DI,SI,DS ;
  2219. ; ;
  2220. ; Registers Destroyed: ;
  2221. ; ;
  2222. ; Calls: ;
  2223. ; ;
  2224. ; History: ;
  2225. ; ;
  2226. ;-----------------------------------------------------------------------;
  2227. assumes ds,nothing
  2228. assumes es,nothing
  2229. cProc get_rover_2,<PUBLIC,NEAR>,<di>
  2230. localV DscBuf,DSC_LEN
  2231. cBegin
  2232. push ax
  2233. push bx
  2234. mov bx, es ; Selector to get rover for
  2235. push ds
  2236. SetKernelDS ds
  2237. mov di, kr2dsc
  2238. mov es, gdtdsc
  2239. mov ds, gdtdsc
  2240. UnSetKernelDS ds
  2241. push si
  2242. mov si, bx
  2243. and si, not 7
  2244. and di, not 7
  2245. MovsDsc
  2246. lea bx, [di-DSC_LEN]
  2247. mov es:[bx].dsc_access, DSC_PRESENT+DSC_DATA
  2248. or bl, SEG_RING
  2249. pop si
  2250. ifdef WOW
  2251. push cx
  2252. mov cx, 1
  2253. DPMICALL WOW_DPMIFUNC_0C
  2254. pop cx
  2255. endif; WOW
  2256. pop ds
  2257. mov es, bx ; Return with ES containing rover
  2258. pop bx
  2259. pop ax
  2260. cEnd
  2261. ;-----------------------------------------------------------------------;
  2262. ; get_rover_232 ;
  2263. ; ;
  2264. ; Entry: ;
  2265. ; ds:esi ;
  2266. ; Returns: ;
  2267. ; ES:0 ;
  2268. ; Error Returns: ;
  2269. ; ;
  2270. ; Registers Preserved: ;
  2271. ; AX,BX,CX,DX,DI,SI,DS ;
  2272. ; ;
  2273. ; Registers Destroyed: ;
  2274. ; ;
  2275. ; Calls: ;
  2276. ; ;
  2277. ; History: ;
  2278. ; ;
  2279. ;-----------------------------------------------------------------------;
  2280. ifndef WOW_x86
  2281. assumes ds,nothing
  2282. assumes es,nothing
  2283. cProc get_rover_232,<PUBLIC,NEAR>,<di>
  2284. localV DscBuf,DSC_LEN
  2285. cBegin
  2286. push eax
  2287. push bx
  2288. SetKernelDS es
  2289. mov bx, kr2dsc
  2290. or bl, SEG_RING
  2291. smov es, ss
  2292. UnSetKernelDS es
  2293. lea di, DscBuf ; ES:DI -> descriptor
  2294. mov eax, ds:[esi].pga_address
  2295. mov [DscBuf].dsc_lbase, ax ; Fill in base address
  2296. shr eax, 16
  2297. mov [DscBuf].dsc_mbase, al
  2298. mov [DscBuf].dsc_hbase, ah
  2299. mov [DscBuf].dsc_limit, 1000h ; Real big limit
  2300. mov [DscBuf].dsc_hlimit, DSC_GRANULARITY
  2301. mov [DscBuf].dsc_access,DSC_PRESENT+DSC_DATA
  2302. DPMICALL 000Ch ; Set descriptor
  2303. mov es, bx
  2304. pop bx
  2305. pop eax
  2306. cEnd
  2307. endif; WOW
  2308. cProc far_get_temp_sel,<FAR,PUBLIC>
  2309. cBegin
  2310. cCall get_temp_sel
  2311. cEnd
  2312. cProc get_temp_sel,<PUBLIC,NEAR>,<ax,cx,di,si>
  2313. localV DscBuf,DSC_LEN
  2314. cBegin
  2315. mov cx, 1
  2316. DPMICALL 0000h ; Get us a selector
  2317. push bx
  2318. mov si, ax ; New selector
  2319. mov bx, es ; Old selector
  2320. ifdef WOW ; LATER Make single dpmicall
  2321. smov es, ss
  2322. lea di, DscBuf
  2323. DPMICALL 000Bh ; Get existing descriptor
  2324. mov DscBuf.dsc_access,DSC_PRESENT+DSC_DATA
  2325. mov DscBuf.dsc_limit,0ffffh
  2326. or DscBuf.dsc_hlimit, 0Fh ; Max length
  2327. mov bx, si
  2328. or bl, SEG_RING
  2329. DPMICALL 000Ch ; Set new descriptor
  2330. else
  2331. push ds
  2332. if ROM
  2333. SetKernelDS
  2334. mov es, gdtdsc
  2335. mov ds, gdtdsc
  2336. UnsetKernelDS
  2337. else
  2338. mov ds, gdtdsc
  2339. mov es, gdtdsc
  2340. endif
  2341. mov di, si
  2342. and di, not 7
  2343. mov si, bx
  2344. and si, not 7
  2345. MovsDsc
  2346. lea bx, [di-DSC_LEN]
  2347. mov [bx].dsc_access,DSC_PRESENT+DSC_DATA
  2348. mov [bx].dsc_limit,0ffffh
  2349. or [bx].dsc_hlimit, 0Fh ; Max length
  2350. or bl, SEG_RING
  2351. pop ds
  2352. endif; WOW
  2353. mov es, bx
  2354. pop bx
  2355. cEnd
  2356. cProc far_free_temp_sel,<PUBLIC,FAR>
  2357. parmW selector
  2358. cBegin
  2359. cCall free_sel,<selector>
  2360. cEnd
  2361. ;-----------------------------------------------------------------------;
  2362. ; get_blotto
  2363. ;
  2364. ;
  2365. ; Entry:
  2366. ; EAX = arena header
  2367. ;
  2368. ; Returns:
  2369. ; BX = Selector points to pga_address (size pga_arena)
  2370. ; Registers Destroyed:
  2371. ;
  2372. ; History:
  2373. ; Sun 31-Jul-1988 16:20:53 -by- David N. Weise [davidw]
  2374. ;
  2375. ;-----------------------------------------------------------------------;
  2376. assumes ds,nothing
  2377. assumes es,nothing
  2378. ifndef WOW_x86
  2379. ;; On WOW_x86 we try to avoid setting selectors since it is slow, we use selector
  2380. ;; 23h to write to anywhere in VDM memory.
  2381. cProc get_blotto,<PUBLIC,NEAR>,<di>
  2382. localV DscBuf,DSC_LEN
  2383. cBegin
  2384. push es
  2385. push bx
  2386. lea di, DscBuf
  2387. SetKernelDS es
  2388. mov bx, blotdsc
  2389. smov es, ss
  2390. UnSetKernelDS es
  2391. or bl, SEG_RING
  2392. push eax
  2393. mov eax, ds:[eax].pga_address
  2394. mov [DscBuf].dsc_lbase,ax
  2395. shr eax, 16
  2396. mov [DscBuf].dsc_mbase,al
  2397. mov [DscBuf].dsc_hbase,ah
  2398. ; Convert pga_size to limit in page granularity
  2399. pop eax
  2400. mov eax, ds:[eax].pga_size ; Get Size in Bytes
  2401. add eax, 4096-1 ; Round up to 4k multiple
  2402. shr eax, 3*4
  2403. mov [DscBuf].dsc_limit,ax
  2404. shr eax,16
  2405. or al, DSC_GRANULARITY
  2406. mov [DscBuf].dsc_hlimit, al
  2407. mov [DscBuf].dsc_access,DSC_PRESENT+DSC_DATA
  2408. DPMICALL 000Ch ; Set up the descriptor
  2409. mov ax, bx
  2410. pop bx
  2411. pop es
  2412. cEnd
  2413. endif;
  2414. ;-----------------------------------------------------------------------;
  2415. ; LongPtrAdd
  2416. ;
  2417. ; Performs segment arithmetic on a long pointer and a DWORD offset
  2418. ; The resulting pointer is normalized to a paragraph boundary.
  2419. ; The offset cannot be greater than 16 megabytes (current Enh Mode
  2420. ; limit on size of an object).
  2421. ;
  2422. ; Entry:
  2423. ;
  2424. ; Returns:
  2425. ; DX:AX new segment:offset
  2426. ;
  2427. ; Error returns:
  2428. ; DX:AX = 0
  2429. ;
  2430. ; Registers Destroyed:
  2431. ; BX,CX
  2432. ;
  2433. ; History:
  2434. ; Mon 19-Dec-1988 18:37:23 -by- David N. Weise [davidw]
  2435. ; Wrote it!
  2436. ;-----------------------------------------------------------------------;
  2437. assumes ds,nothing
  2438. assumes es,nothing
  2439. ifdef WOW
  2440. LPTRADDWOW_SETBASE equ 01h
  2441. ;cProc LongPtrAddWOW,<PUBLIC,FAR>,<si,di>
  2442. ; parmD long_ptr
  2443. ; parmD delta
  2444. ; parmW RefSelector
  2445. ; parmW flBaseSetting
  2446. ;
  2447. ; effectively pops RefSelector and flBaseSetting into dx and ax.
  2448. ; and jumps to longptrAddWorker.
  2449. ;
  2450. ; RefSelector is used only if the descriptor needs to be set.
  2451. ;
  2452. labelFP <PUBLIC,LongPtrAddWOW>
  2453. pop ax
  2454. pop dx ; far return address
  2455. mov bx,sp
  2456. xchg ax, ss:[bx] ; replace the 'dword' with the return address
  2457. xchg dx, ss:[bx+2]
  2458. jmps LongPtrAddWorker ; ax = flags; dx = reference selector
  2459. labelFP <PUBLIC,LongPtrAdd>
  2460. mov ax, LPTRADDWOW_SETBASE
  2461. xor dx, dx
  2462. ; fall through
  2463. cProc LongPtrAddWorker,<PUBLIC,FAR>,<si,di>
  2464. parmD long_ptr
  2465. parmD delta
  2466. localV DscBuf,DSC_LEN
  2467. localW flBaseSetting
  2468. localW RefSelector
  2469. cBegin
  2470. mov flBaseSetting, ax ; save in localvariables
  2471. mov RefSelector, dx
  2472. or dx, dx ; if RefSelector is nonzero
  2473. jz @F ; use it for querying descriptor info.
  2474. xchg dx, word ptr long_ptr[2] ; and store the selector to be set in
  2475. mov RefSelector, dx ; the localvariable
  2476. @@:
  2477. else
  2478. cProc LongPtrAdd,<PUBLIC,FAR>,<si,di>
  2479. parmD long_ptr
  2480. parmD delta
  2481. localV DscBuf,DSC_LEN
  2482. cBegin
  2483. endif
  2484. mov bx,word ptr long_ptr[2]
  2485. lea di, DscBuf
  2486. smov es, ss
  2487. DPMICALL 000Bh ; Pick up old descriptor
  2488. mov ax,word ptr long_ptr[0] ; get the pointer into SI:AX
  2489. and ax,0FFF0h
  2490. mov si, DscBuf.dsc_lbase ; DX:SI gets old base
  2491. mov dl, DscBuf.dsc_mbase
  2492. mov dh, DscBuf.dsc_hbase
  2493. add si, ax ; Add in old pointer offset
  2494. adc dx, 0
  2495. mov cx, word ptr delta[2] ; add the segment and MSW
  2496. test cx, 0FF00h ; bigger than 16Meg?
  2497. ifdef WOW
  2498. jz @F
  2499. test flBaseSetting, LPTRADDWOW_SETBASE
  2500. jnz lptr_mustset
  2501. jmp short lpa_too_big
  2502. @@:
  2503. else
  2504. jnz short lpa_too_big
  2505. endif
  2506. add si, word ptr delta[0] ; add the offset and LSW
  2507. adc dx, cx
  2508. ifdef WOW
  2509. lptr_mustset:
  2510. endif
  2511. mov cx, 1 ; Calculate # selectors now in array
  2512. lsl ecx, dword ptr long_ptr[2]
  2513. jnz short trash
  2514. Limit_to_Selectors ecx
  2515. trash:
  2516. ifdef WOW
  2517. test flBaseSetting, LPTRADDWOW_SETBASE
  2518. jz lptr_dontset
  2519. cmp RefSelector, 0
  2520. jz @F
  2521. mov bx, RefSelector ; get the actual selector to be set
  2522. mov word ptr long_ptr[2], bx
  2523. @@:
  2524. endif
  2525. mov DscBuf.dsc_lbase, si ; Put new base back in descriptor
  2526. mov DscBuf.dsc_mbase, dl
  2527. mov DscBuf.dsc_hbase, dh
  2528. call fill_in_selector_array
  2529. ifdef WOW
  2530. lptr_dontset:
  2531. test word ptr delta[2], 0ff00h
  2532. jz @F
  2533. mov cx, word ptr delta[2]
  2534. jmps lpa_too_big
  2535. @@:
  2536. endif
  2537. mov dx,word ptr long_ptr[2]
  2538. mov ax,word ptr long_ptr[0]
  2539. and ax, 0Fh
  2540. jnc short lpa_exit
  2541. lpa_too_big:
  2542. xor ax,ax
  2543. xor dx,dx
  2544. lpa_exit:
  2545. smov es,0
  2546. cEnd
  2547. ;-----------------------------------------------------------------------;
  2548. ; SetSelectorBase
  2549. ;
  2550. ; Sets the base and limit of the given selector.
  2551. ;
  2552. ; Entry:
  2553. ; parmW selector
  2554. ; parmD selbase
  2555. ;
  2556. ; Returns:
  2557. ; AX = selector
  2558. ;
  2559. ; Error Returns:
  2560. ; AX = 0
  2561. ;
  2562. ; History:
  2563. ; Tue 23-May-1989 21:10:29 -by- David N. Weise [davidw]
  2564. ; Wrote it!
  2565. ;-----------------------------------------------------------------------;
  2566. assumes ds,nothing
  2567. assumes es,nothing
  2568. cProc SetSelectorBase,<PUBLIC,FAR>
  2569. parmW selector
  2570. parmD selbase
  2571. cBegin
  2572. push bx
  2573. push cx
  2574. push dx
  2575. mov cx, selbase.hi
  2576. mov dx, selbase.lo
  2577. mov bx, selector
  2578. ifdef WOW
  2579. DPMICALL 0007h ; Set Segment Base Address
  2580. else
  2581. push ds
  2582. if ROM
  2583. SetKernelDS
  2584. mov ds, gdtdsc
  2585. UnsetKernelDS
  2586. else
  2587. mov ds, gdtdsc
  2588. endif
  2589. push bx
  2590. and bl, not 7
  2591. mov ds:[bx].dsc_lbase, dx
  2592. mov ds:[bx].dsc_mbase, cl
  2593. mov ds:[bx].dsc_hbase, ch
  2594. pop bx
  2595. pop ds
  2596. endif; WOW
  2597. pop dx
  2598. pop cx
  2599. pop bx
  2600. mov ax,selector
  2601. cEnd
  2602. ;-----------------------------------------------------------------------;
  2603. ; GetSelectorLimit
  2604. ;
  2605. ; Sets the limit of the given selector.
  2606. ;
  2607. ; Entry:
  2608. ; parmW selector
  2609. ;
  2610. ; Returns:
  2611. ; DX:AX = limit of selector
  2612. ;
  2613. ; Registers Destroyed:
  2614. ;
  2615. ; History:
  2616. ; Tue 23-May-1989 21:10:29 -by- David N. Weise [davidw]
  2617. ; Wrote it!
  2618. ;-----------------------------------------------------------------------;
  2619. assumes ds,nothing
  2620. assumes es,nothing
  2621. cProc GetSelectorLimit,<PUBLIC,FAR>
  2622. parmW selector
  2623. cBegin
  2624. xor eax, eax ; In case lsl fails
  2625. lsl eax, dword ptr selector
  2626. mov edx, eax
  2627. shr edx, 16
  2628. cEnd
  2629. ;-----------------------------------------------------------------------;
  2630. ; SetSelectorLimit
  2631. ;
  2632. ; Sets the limit of the given selector.
  2633. ;
  2634. ; Entry:
  2635. ; parmW selector
  2636. ; parmD sellimit
  2637. ;
  2638. ; Returns:
  2639. ; AX = 0 success
  2640. ;
  2641. ; Registers Destroyed:
  2642. ;
  2643. ; History:
  2644. ; Tue 23-May-1989 21:10:29 -by- David N. Weise [davidw]
  2645. ; Wrote it!
  2646. ;-----------------------------------------------------------------------;
  2647. assumes ds,nothing
  2648. assumes es,nothing
  2649. cProc SetSelectorLimit,<PUBLIC,FAR>
  2650. parmW selector
  2651. parmD sellimit
  2652. localV DscBuf,DSC_LEN
  2653. cBegin
  2654. ifdef WOW
  2655. mov bx, selector
  2656. mov dx, word ptr sellimit[0]
  2657. mov cx, word ptr sellimit[2]
  2658. DPMICALL 0008h
  2659. else
  2660. push es
  2661. push di
  2662. mov bx,selector
  2663. push ds
  2664. if ROM
  2665. SetKernelDS
  2666. mov ds, gdtdsc
  2667. UnsetKernelDS
  2668. else
  2669. mov ds, gdtdsc
  2670. endif
  2671. and bl, not 7
  2672. mov ax,sellimit.lo
  2673. mov [bx].dsc_limit,ax
  2674. mov ax,sellimit.hi
  2675. and al,0Fh ; AND out flags
  2676. and [bx].dsc_hlimit,0F0h ; AND out hi limit
  2677. or [bx].dsc_hlimit,al
  2678. pop ds
  2679. pop di
  2680. pop es
  2681. endif; WOW
  2682. xor ax,ax ; for now always return success
  2683. cEnd
  2684. ;-----------------------------------------------------------------------;
  2685. ; SelectorAccessRights
  2686. ;
  2687. ; Sets the access and other bytes of the given selector.
  2688. ;
  2689. ; Entry:
  2690. ; parmW selector
  2691. ; parmW getsetflag
  2692. ; parmD selrights
  2693. ;
  2694. ; Returns:
  2695. ; AX = 0 success
  2696. ;
  2697. ; Registers Destroyed:
  2698. ;
  2699. ; History:
  2700. ; Tue 23-May-1989 21:10:29 -by- David N. Weise [davidw]
  2701. ; Wrote it!
  2702. ;-----------------------------------------------------------------------;
  2703. assumes ds,nothing
  2704. assumes es,nothing
  2705. cProc SelectorAccessRights,<PUBLIC,FAR>
  2706. parmW selector
  2707. parmW getsetflag
  2708. parmW selrights
  2709. cBegin
  2710. mov bx, selector
  2711. lar eax, ebx ; Get current access rights
  2712. shr eax, 8 ; in AX
  2713. cmp getsetflag,0
  2714. jnz short sar_set
  2715. and ax, 0D01Eh ; Hide bits they can't play with
  2716. jmps sar_exit
  2717. sar_set:
  2718. mov cx, selrights
  2719. and cx, 0D01Eh ; Zap bits they can't set and
  2720. and ax, NOT 0D01Eh ; get them from existing access rights
  2721. or cx, ax
  2722. DPMICALL 0009h ; Set new access rights
  2723. xor ax,ax ; for now always return success
  2724. sar_exit:
  2725. cEnd
  2726. cProc SetKernelCSDwordProc,<PUBLIC,NEAR>,<ax,bx,ds>
  2727. parmw addr
  2728. parmw hiword
  2729. parmw loword
  2730. cBegin
  2731. SetKernelDS
  2732. mov ds, MyCSAlias
  2733. UnSetKernelDS
  2734. mov bx, addr
  2735. mov ax, loword
  2736. mov [bx], ax
  2737. mov ax, hiword
  2738. mov [bx+2], ax
  2739. cEnd
  2740. cProc GetKernelDataSeg,<PUBLIC,NEAR>
  2741. cBegin nogen
  2742. mov ax, cs:MyCSDS
  2743. ret
  2744. cEnd nogen
  2745. cProc SetKernelDSProc,<PUBLIC,NEAR>
  2746. cBegin nogen
  2747. mov ds, cs:MyCSDS
  2748. ret
  2749. cEnd nogen
  2750. cProc SetKernelESProc,<PUBLIC,NEAR>
  2751. cBegin nogen
  2752. mov es, cs:MyCSDS
  2753. ret
  2754. cEnd nogen
  2755. assumes ds, nothing
  2756. assumes es, nothing
  2757. cProc PreallocArena,<PUBLIC,NEAR>
  2758. cBegin nogen
  2759. push ds
  2760. push eax
  2761. cCall alloc_arena_header,<eax>
  2762. call SetKernelDSProc
  2763. ReSetKernelDS
  2764. mov temp_arena, eax
  2765. or eax, eax ; Set flags for caller
  2766. pop eax
  2767. pop ds
  2768. UnSetKernelDS
  2769. ret
  2770. cEnd nogen
  2771. assumes ds, nothing
  2772. assumes es, nothing
  2773. cProc alloc_arena_header,<PUBLIC,NEAR>,<es>
  2774. parmD Address
  2775. localV DscBuf,DSC_LEN
  2776. cBegin
  2777. SetKernelDS es
  2778. push ebx
  2779. xor eax, eax
  2780. cmp temp_arena, eax ; Have one waiting?
  2781. je short aah_look ; no, get one
  2782. xchg temp_arena, eax ; Use the waiting selector
  2783. jmp aah_found
  2784. aah_look:
  2785. cmp FreeArenaCount, 0
  2786. jnz aah_ok
  2787. ; Out of arenas, try to get
  2788. push ecx
  2789. push si
  2790. push di
  2791. xor bx, bx
  2792. mov cx, ARENA_INCR_BYTES
  2793. DPMICALL 0501h
  2794. jc short aah_no_memory
  2795. if 0
  2796. push si
  2797. push di
  2798. mov ax, 0600h ; Page lock it
  2799. mov di, ARENA_INCR_BYTES
  2800. xor si, si
  2801. int 31h
  2802. pop di
  2803. pop si
  2804. jnc short aah_got_memory
  2805. give_it_back:
  2806. DPMICALL 0502h ; No good, give it back
  2807. else
  2808. jmp short aah_got_memory
  2809. endif
  2810. aah_no_memory:
  2811. pop di
  2812. pop si
  2813. pop ecx
  2814. xor eax, eax ; We are REALLY out of arenas!
  2815. jmp aah_exit
  2816. aah_got_memory:
  2817. shl ebx, 16
  2818. mov bx, cx ; Address of our new arenas
  2819. cCall get_arena_pointer32,<ds>; Arena of burgermaster
  2820. sub ebx, [eax].pga_address ; Above present arenas?
  2821. lea ecx, [ebx+ARENA_INCR_BYTES+0FFFh]
  2822. shr ecx, 12 ; #pages selector must cover
  2823. dec ecx ; limit with page granularity
  2824. cmp ecx, HighestArena
  2825. jbe short aah_limitOK
  2826. mov HighestArena, ecx
  2827. push es
  2828. push bx
  2829. mov bx, ds
  2830. lea di, DscBuf
  2831. smov es, ss
  2832. DPMICALL 000Bh ; Get DS descriptor
  2833. mov [DscBuf].dsc_limit, cx ; Set the new limit in the descriptor
  2834. shr ecx, 16
  2835. and cl, 0fh ; hlimit bits
  2836. and [DscBuf].dsc_hlimit, not 0fh; Zap old ones
  2837. or cl, DSC_GRANULARITY ; Granularity bit
  2838. or [DscBuf].dsc_hlimit, cl
  2839. DPMICALL 000Ch ; Set new limit
  2840. pop bx
  2841. pop es
  2842. aah_limitOK:
  2843. mov cx, ARENA_INCR_BYTES
  2844. shr cx, 5 ; # arenas to add
  2845. aah_loop:
  2846. cCall free_arena_header,<ebx> ; Free up all our new arenas
  2847. add ebx, size GlobalArena32
  2848. loop aah_loop
  2849. pop di
  2850. pop si
  2851. pop ecx
  2852. aah_ok:
  2853. mov eax, FreeArenaList
  2854. if KDEBUG
  2855. inc eax
  2856. jnz short aah_ook
  2857. int 3
  2858. int 3
  2859. aah_ook:
  2860. dec eax
  2861. endif
  2862. mov ebx, ds:[eax.pga_next]
  2863. mov FreeArenaList, ebx
  2864. dec FreeArenaCount
  2865. aah_found:
  2866. mov ebx, Address
  2867. mov ds:[eax.pga_address], ebx
  2868. mov dword ptr ds:[eax.pga_count], 0
  2869. aah_exit:
  2870. pop ebx
  2871. cEnd
  2872. assumes ds, nothing
  2873. assumes es, nothing
  2874. cProc free_arena_header,<PUBLIC,NEAR>,<es>
  2875. parmD arena
  2876. cBegin
  2877. push eax
  2878. push ebx
  2879. SetKernelDS es
  2880. CheckDS
  2881. mov ebx, arena
  2882. mov eax, FreeArenaList
  2883. mov ds:[ebx.pga_next], eax
  2884. mov FreeArenaList, ebx
  2885. inc FreeArenaCount
  2886. pop ebx
  2887. pop eax
  2888. cEnd
  2889. assumes ds, nothing
  2890. assumes es, nothing
  2891. cProc FarAssociateSelector32,<PUBLIC,FAR>
  2892. parmW Selector
  2893. parmD ArenaPtr
  2894. cBegin
  2895. cCall AssociateSelector32,<Selector,ArenaPtr>
  2896. cEnd
  2897. cProc AssociateSelector32,<PUBLIC,NEAR>,<ds,es>
  2898. parmW Selector
  2899. parmD ArenaPtr
  2900. cBegin
  2901. CheckDS
  2902. SetKernelDS es
  2903. push eax
  2904. push ebx
  2905. movzx ebx, Selector
  2906. and bl, NOT SEG_RING_MASK
  2907. shr bx, 1
  2908. if KDEBUG
  2909. cmp bx, SelTableLen
  2910. jb short as_ok
  2911. INT3_NEVER
  2912. INT3_NEVER
  2913. as_ok:
  2914. endif
  2915. add ebx, SelTableStart
  2916. mov eax, ArenaPtr
  2917. mov ds:[ebx], eax
  2918. pop ebx
  2919. pop eax
  2920. cEnd
  2921. assumes ds, nothing
  2922. assumes es, nothing
  2923. cProc far_get_arena_pointer32,<PUBLIC,FAR>
  2924. parmW Selector
  2925. cBegin
  2926. cCall get_arena_pointer32,<Selector>
  2927. cEnd
  2928. cProc get_arena_pointer32,<PUBLIC,NEAR>
  2929. parmW Selector
  2930. cBegin
  2931. CheckDS
  2932. push es
  2933. SetKernelDS es
  2934. push ebx
  2935. movzx ebx, Selector
  2936. and bl, not SEG_RING_MASK
  2937. shr bx, 1
  2938. cmp bx, SelTableLen
  2939. jb short gap_ok
  2940. xor eax, eax ; Bogus, return null
  2941. jmps gap_exit
  2942. gap_ok:
  2943. add ebx, SelTableStart
  2944. mov eax, ds:[ebx]
  2945. if ROM
  2946. ; hack for ROM-owned selectors. these do not have arenas
  2947. ; but the owner is stored in the low word. ack ack ack!!
  2948. ;
  2949. cmp eax, 0FFFF0000h
  2950. jb short @F
  2951. xor eax, eax
  2952. @@:
  2953. endif
  2954. if KDEBUG
  2955. or eax, eax
  2956. jz short gap_exit ; Bogus, return null
  2957. push si
  2958. mov si, ds:[eax].pga_handle
  2959. sel_check si
  2960. or si, si
  2961. jz short gap32_match ; Boot time...
  2962. sub ebx, SelTableStart
  2963. shl bx, 1
  2964. cmp bx, si
  2965. je short gap32_match
  2966. xor eax, eax ; put back in 5 feb 90, alias avoided
  2967. ;;; xor eax, eax ; Removed - may be an alias!
  2968. gap32_match:
  2969. pop si
  2970. endif
  2971. gap_exit:
  2972. pop ebx
  2973. pop es
  2974. cEnd
  2975. assumes ds, nothing
  2976. assumes es, nothing
  2977. cProc FarGetOwner,<PUBLIC,FAR>,<bx>
  2978. parmW Selector
  2979. cBegin
  2980. cCall GetOwner,<Selector>
  2981. cEnd
  2982. cProc GetOwner,<PUBLIC,NEAR>,<bx,es>
  2983. parmW Selector
  2984. cBegin
  2985. GENTER32
  2986. ;;;push eax ;; why??? ax gets trashed anyway.
  2987. cCall get_arena_pointer32,<Selector>
  2988. if ROM
  2989. or eax, eax
  2990. jnz short @F
  2991. cCall GetROMOwner,<selector>
  2992. jmp short go_solong
  2993. @@:
  2994. endif
  2995. or eax, eax
  2996. jz go_solong
  2997. mov bx, ds:[eax].pga_owner
  2998. ;;;pop eax
  2999. mov ax, bx
  3000. go_solong:
  3001. GLEAVE32
  3002. cEnd
  3003. assumes ds, nothing
  3004. assumes es, nothing
  3005. cProc FarSetOwner,<PUBLIC,FAR>
  3006. parmW Selector
  3007. parmW owner
  3008. cBegin
  3009. cCall SetOwner,<Selector,owner>
  3010. cEnd
  3011. assumes ds, nothing
  3012. assumes es, nothing
  3013. cProc SetOwner,<PUBLIC,NEAR>,<ds,es>
  3014. parmW Selector
  3015. parmW owner
  3016. cBegin
  3017. GENTER32 ; Assume ds not set!
  3018. push eax
  3019. cCall get_arena_pointer32,<Selector>
  3020. push owner
  3021. pop ds:[eax].pga_owner
  3022. pop eax
  3023. GLEAVE32
  3024. cEnd
  3025. assumes ds, nothing
  3026. assumes es, nothing
  3027. cProc PageLockLinear,<PUBLIC,NEAR>,<ax,bx,cx,si,di>
  3028. parmD address
  3029. parmD len
  3030. cBegin
  3031. mov bx, word ptr address+2
  3032. mov cx, word ptr address
  3033. mov si, word ptr len+2
  3034. mov di, word ptr len
  3035. DPMICALL 0600h
  3036. ; Let it return with carry flag from int 31h
  3037. cEnd
  3038. assumes ds, nothing
  3039. assumes es, nothing
  3040. cProc FarValidatePointer,<PUBLIC,FAR>
  3041. parmD lpointer
  3042. cBegin
  3043. cCall ValidatePointer,<lpointer>
  3044. cEnd
  3045. cProc ValidatePointer,<PUBLIC,NEAR>
  3046. parmD lpointer
  3047. cBegin
  3048. lar ax, lpointer.sel
  3049. jnz short bad_p ; Really bad selector
  3050. test ah, DSC_PRESENT ; Must be present
  3051. jz short bad_p
  3052. lsl eax, dword ptr lpointer.sel
  3053. movzx ecx, lpointer.off
  3054. cmp eax, ecx ; Is the offset valid?
  3055. jae short good_p
  3056. bad_p:
  3057. xor ax, ax
  3058. jmps vp_done
  3059. good_p:
  3060. mov ax, 1
  3061. vp_done:
  3062. cEnd
  3063. assumes ds, nothing
  3064. assumes es, nothing
  3065. OneParaBytes dw 10h
  3066. cProc SelToSeg,<PUBLIC,NEAR>,<dx>
  3067. parmW selector
  3068. cBegin
  3069. cCall get_physical_address,<selector>
  3070. div cs:OneParaBytes ; Smaller than rotates
  3071. cEnd
  3072. cProc SegToSelector,<PUBLIC,NEAR>,<bx,cx,di,ds>
  3073. parmW smegma
  3074. cBegin
  3075. mov bx, smegma
  3076. DPMICALL 0002h ; Make win386 do it
  3077. cEnd
  3078. ;-----------------------------------------------------------------------;
  3079. ; set_discarded_sel_owner
  3080. ;
  3081. ; Sets the owner of a selector that points to a discarded object,
  3082. ; which lives in the limit field.
  3083. ;
  3084. ; Entry:
  3085. ; BX = selector to mark
  3086. ; ES = owner
  3087. ;
  3088. ; Returns:
  3089. ; nothing
  3090. ;
  3091. ; Registers Destroyed:
  3092. ; BX
  3093. ;
  3094. ; History:
  3095. ; Sun 03-Dec-1989 21:02:24 -by- David N. Weise [davidw]
  3096. ; Wrote it!
  3097. ;-----------------------------------------------------------------------;
  3098. assumes ds,nothing
  3099. assumes es,nothing
  3100. cProc set_discarded_sel_owner,<PUBLIC,FAR>
  3101. localV DscBuf,DSC_LEN
  3102. cBegin
  3103. push cx
  3104. push di
  3105. mov cx, es
  3106. if KDEBUG
  3107. ifdef WOW
  3108. lea di, DscBuf
  3109. smov es, ss
  3110. DPMICALL 000Bh
  3111. push cx
  3112. xor cx,cx ; For debug build write 0 to LDT
  3113. mov DscBuf.dsc_owner, cx
  3114. DPMICALL 000Ch
  3115. pop cx
  3116. endif
  3117. endif
  3118. push ds
  3119. if ROM
  3120. SetKernelDS
  3121. mov ds, gdtdsc
  3122. UnsetKernelDS
  3123. else
  3124. mov ds, gdtdsc
  3125. endif
  3126. push bx
  3127. and bl, not 7
  3128. mov [bx].dsc_owner, cx
  3129. pop bx
  3130. pop ds
  3131. push ds
  3132. SetKernelDS
  3133. mov ds, pGlobalHeap
  3134. UnSetKernelDS
  3135. cCall AssociateSelector32,<bx,0,cx> ; And save in selector table
  3136. pop ds
  3137. mov es, cx
  3138. pop di
  3139. pop cx
  3140. cEnd
  3141. ;-----------------------------------------------------------------------;
  3142. ; SetResourceOwner
  3143. ;
  3144. ; Sets the owner of a selector that points to a not present resource
  3145. ;
  3146. ; Entry:
  3147. ;
  3148. ; Returns:
  3149. ; nothing
  3150. ;
  3151. ; Registers Destroyed:
  3152. ;
  3153. ; History:
  3154. ;-----------------------------------------------------------------------;
  3155. assumes ds,nothing
  3156. assumes es,nothing
  3157. cProc SetResourceOwner,<PUBLIC,NEAR>,<ax,bx,cx,di,ds,es>
  3158. parmW selector
  3159. parmW owner
  3160. parmW selCount
  3161. localV DscBuf,DSC_LEN
  3162. cBegin
  3163. mov bx, selector
  3164. mov cx, owner
  3165. ifdef WOW
  3166. smov es, ss
  3167. lea di, DscBuf
  3168. DPMICALL 000Bh ; Get current descriptor
  3169. mov DscBuf.dsc_owner, cx
  3170. mov word ptr DscBuf.dsc_access, (DSC_DISCARDABLE SHL 8) + DSC_DATA
  3171. mov cx,selCount
  3172. mov DscBuf.dsc_hbase, cl ; Save number of selectors here
  3173. DPMICALL 000Ch ; Set it with new owner
  3174. else
  3175. push ds
  3176. if ROM
  3177. SetKernelDS
  3178. mov ds, gdtdsc
  3179. UnsetKernelDS
  3180. else
  3181. mov ds, gdtdsc
  3182. endif
  3183. push bx
  3184. and bl, not 7
  3185. mov [bx].dsc_owner, cx
  3186. mov word ptr [bx].dsc_access, (DSC_DISCARDABLE SHL 8) + DSC_DATA
  3187. mov cx, selCount
  3188. mov [bx].dsc_hbase, cl ; Save number of selectors here
  3189. pop bx
  3190. pop ds
  3191. endif; WOW
  3192. SetKernelDS
  3193. mov ds, pGlobalHeap
  3194. UnSetKernelDS
  3195. cCall AssociateSelector32,<bx,0,owner> ; And save in selector table
  3196. cEnd
  3197. cProc GetAccessWord,<PUBLIC,NEAR>
  3198. parmW selector
  3199. cBegin
  3200. lar eax, dword ptr selector ; 386 or better, can use LAR
  3201. shr eax, 8
  3202. cEnd
  3203. ;-----------------------------------------------------------------------;
  3204. ; DPMIProc
  3205. ;
  3206. ; Called NEAR by the DPMICALL macro -
  3207. ; this is better than intercepting int 31h
  3208. ;
  3209. ; By sheer fluke, all intercepts return with
  3210. ; Carry clear ie no error.
  3211. ;
  3212. ;-----------------------------------------------------------------------;
  3213. cProc DPMIProc,<PUBLIC,NEAR>
  3214. cBegin nogen
  3215. if 0
  3216. cmp ax,WOW_DPMIFUNC_0C
  3217. jne @f
  3218. INT3_TEST
  3219. push ds
  3220. SetKernelDS ds
  3221. cmp high0c,cx
  3222. ja popit
  3223. mov high0c,cx
  3224. popit:
  3225. pop ds
  3226. @@:
  3227. endif
  3228. ifdef WOW
  3229. cmp ax,501h
  3230. jne normal
  3231. push eax
  3232. push edx
  3233. shl ebx,16 ; ebx = bx:cx
  3234. mov bx,cx
  3235. xor eax,eax
  3236. mov ecx,PAGE_READWRITE
  3237. mov edx,MEM_COMMIT_RESERVE
  3238. cCall VirtualAlloc,<eax,ebx,edx,ecx>
  3239. mov bx,dx ; DPMI returns BX:CX - linear Address
  3240. mov cx,ax
  3241. mov si,dx ; FAKE dpmi "handle" - linear Address
  3242. mov di,ax
  3243. or ax,dx ; NULL is Error
  3244. pop edx
  3245. pop eax
  3246. clc
  3247. jnz @f ; OK Jump
  3248. stc ; else set error
  3249. @@:
  3250. ret
  3251. normal:
  3252. endif ; WOW
  3253. or ah, ah
  3254. jz @F
  3255. ife KDEBUG
  3256. ifdef WOW_x86
  3257. ;
  3258. ; If it is the wow set selector call we will just set the selector
  3259. ; directly using int 2a (only for the single selector case)
  3260. ;
  3261. cmp ax,WOW_DPMIFUNC_0C
  3262. jne CallServer
  3263. cmp cx,1
  3264. jne CallServer
  3265. call WowSetSelector
  3266. jc CallServer
  3267. ret
  3268. endif
  3269. endif
  3270. CallServer:
  3271. ifndef WOW
  3272. int 31h ; Nope, call DPMI server
  3273. ret
  3274. else
  3275. test word ptr [prevInt31Proc + 2],0FFFFh
  3276. jz dp30
  3277. dp20:
  3278. pushf
  3279. call [prevInt31Proc]
  3280. ret
  3281. endif
  3282. @@:
  3283. ifdef WOW
  3284. cmp gdtdsc, 0 ; Can we party?
  3285. jz CallServer ; Nope
  3286. endif
  3287. push ds
  3288. mov ds, gdtdsc
  3289. ifdef WOW
  3290. or al, al
  3291. jnz @F
  3292. mov ax, WOW_DPMIFUNC_00
  3293. pop ds
  3294. jmp CallServer
  3295. @@:
  3296. endif
  3297. cmp al, 0Bh
  3298. jne short @F
  3299. push si ; Get Descriptor - used very often!
  3300. mov si, bx
  3301. and si, not 7
  3302. MovsDsc
  3303. lea di, [di-DSC_LEN] ; Restore DI
  3304. pop si
  3305. pop ds
  3306. ret
  3307. ifndef WOW
  3308. @@:
  3309. cmp al, 0Ch
  3310. jne @F
  3311. push bx ; Set Descriptor
  3312. and bl, not 7
  3313. mov ax, es:[di] ; This looks slow but it isn't...
  3314. mov ds:[bx], ax
  3315. mov ax, es:[di][2]
  3316. mov ds:[bx][2], ax
  3317. mov ax, es:[di][4]
  3318. mov ds:[bx][4], ax
  3319. mov ax, es:[di][6]
  3320. mov ds:[bx][6], ax
  3321. if 0 ;;ROM and KDEBUG
  3322. call CheckROMSelector
  3323. endif
  3324. pop bx
  3325. pop ds
  3326. ret
  3327. @@:
  3328. cmp al, 07h ; Set Segment Base Address
  3329. jne @F
  3330. push bx
  3331. and bl, not 7
  3332. mov ds:[bx].dsc_lbase, dx
  3333. mov ds:[bx].dsc_mbase, cl
  3334. mov ds:[bx].dsc_hbase, ch
  3335. pop bx
  3336. pop ds
  3337. ret
  3338. endif
  3339. @@:
  3340. cmp al, 06h ; Get Segment Base Address
  3341. jne @F
  3342. push bx
  3343. and bl, not 7
  3344. mov dx, ds:[bx].dsc_lbase
  3345. mov cl, ds:[bx].dsc_mbase
  3346. mov ch, ds:[bx].dsc_hbase
  3347. pop bx
  3348. pop ds
  3349. ret
  3350. ifndef WOW
  3351. @@:
  3352. cmp al, 09h ; Set Descriptor Access Rights
  3353. jne @F
  3354. push bx
  3355. and bl, not 7
  3356. mov word ptr ds:[bx].dsc_access, cx
  3357. if 0 ;;ROM and KDEBUG
  3358. call CheckROMSelector
  3359. endif
  3360. pop bx
  3361. pop ds
  3362. ret
  3363. endif
  3364. @@:
  3365. pop ds
  3366. jmp CallServer
  3367. ifdef WOW
  3368. dp30: int 31h
  3369. ret
  3370. endif
  3371. cEnd nogen
  3372. ife KDEBUG
  3373. ifdef WOW_x86
  3374. ;-----------------------------------------------------------------------;
  3375. ; WowSetSelector
  3376. ;
  3377. ; Entry
  3378. ; BX contains selector #
  3379. ;
  3380. ; Exit
  3381. ; CY clear for success
  3382. ;
  3383. ;
  3384. ;-----------------------------------------------------------------------;
  3385. cProc WowSetSelector,<PUBLIC,NEAR>
  3386. cBegin nogen
  3387. push ds
  3388. push es
  3389. push eax
  3390. push ecx
  3391. push edx
  3392. push ebx
  3393. push ebp
  3394. SetKernelDS ds
  3395. ;
  3396. ; Check to see if we can do this
  3397. ;
  3398. mov edx, FlatAddressArray
  3399. or edx, edx
  3400. stc
  3401. jz wss50
  3402. ;
  3403. ; put the base of the selector in the flat address array
  3404. ;
  3405. mov es,gdtdsc
  3406. and bx, NOT SEG_RING
  3407. mov ax, FLAT_SEL
  3408. mov ds, ax
  3409. mov ah, es:[bx].dsc_hbase
  3410. mov al, es:[bx].dsc_mbase
  3411. shl eax,16
  3412. mov ax, es:[bx].dsc_lbase
  3413. movzx ecx,bx
  3414. shr ecx,1 ; dword index from selector index
  3415. add ecx, edx ; point to proper spot in array
  3416. mov [ecx], eax
  3417. ;
  3418. ; Form the limit of the selector
  3419. ;
  3420. movzx dx, byte ptr es:[bx].dsc_hlimit
  3421. and dx,0fh ; remove gran etc.
  3422. shl edx, 16
  3423. mov dx, es:[bx].dsc_limit
  3424. ;
  3425. ; Adjust for granularity
  3426. ;
  3427. test es:[bx].dsc_hlimit, DSC_GRANULARITY
  3428. jz wss10
  3429. shl edx,12
  3430. or edx,0fffh
  3431. ;
  3432. ; Verify that the base/limit combination is allowed
  3433. ; duplicate of code in dpmi32/i386/dpmi386.c <DpmiSetDescriptorEntry>
  3434. ;
  3435. wss10: cmp edx,07ffeffffh
  3436. ja wss30
  3437. mov ecx,eax
  3438. add ecx,edx
  3439. cmp ecx,07ffeffffh
  3440. jb wss40
  3441. ;
  3442. ; Limit is too high, so adjust it downward
  3443. ;
  3444. wss30: mov edx,07ffeffffh
  3445. sub edx,eax
  3446. sub edx,0fffh
  3447. ;
  3448. ; fix for granularity
  3449. ;
  3450. test es:[bx].dsc_hlimit, DSC_GRANULARITY
  3451. jz wss35
  3452. shr edx,12
  3453. ;
  3454. ; store the new limit in the descriptor table
  3455. ;
  3456. wss35: mov es:[bx].dsc_limit,dx
  3457. shr edx,16
  3458. movzx ax,es:[bx].dsc_hlimit
  3459. and ax,0f0h ; mask for gran etc
  3460. and dx,00fh ; mask for limit bits
  3461. or dx,ax ; put back gran etc
  3462. mov es:[bx].dsc_hlimit,dl
  3463. ;
  3464. ; Call the system to set the selector
  3465. ;
  3466. ; int 2a special case for wow:
  3467. ;
  3468. ; eax = 0xf0f0f0f1
  3469. ; ebp = 0xf0f0f0f1
  3470. ; ebx = selector
  3471. ; ecx = first dword of the descriptor (LODWORD)
  3472. ; edx = second dword of the descriptor (HIDWORD)
  3473. wss40: mov eax, 0f0f0f0f1h
  3474. mov ebp, 0f0f0f0f1h
  3475. mov ecx, dword ptr es:[bx]
  3476. mov edx, dword ptr es:[bx+4]
  3477. movzx ebx,bx
  3478. or bl, 3
  3479. int 02ah
  3480. wss50:
  3481. pop ebp
  3482. pop ebx
  3483. pop edx
  3484. pop ecx
  3485. pop eax
  3486. pop es
  3487. pop ds
  3488. ret
  3489. cEnd nogen
  3490. endif ; WOW_x86
  3491. endif
  3492. if ROM
  3493. ;-----------------------------------------------------------------------------
  3494. ;
  3495. ; Functions for ROM Windows
  3496. ;
  3497. ;
  3498. ;-----------------------------------------------------------------------------
  3499. ;
  3500. ; HocusROMBase
  3501. ;
  3502. ;-----------------------------------------------------------------------------
  3503. assumes ds,nothing
  3504. assumes es,nothing
  3505. assumes fs,nothing
  3506. assumes gs,nothing
  3507. cProc HocusROMBase, <PUBLIC, FAR>
  3508. parmW selector
  3509. cBegin
  3510. push bx
  3511. push cx
  3512. push dx
  3513. push ds
  3514. SetKernelDS
  3515. mov bx, selector
  3516. DPMICALL 0006h
  3517. mov ax, cx
  3518. shl eax, 16
  3519. mov ax, dx
  3520. sub eax, lmaHiROM
  3521. jb not_in_hi_rom
  3522. cmp eax, cbHiROM
  3523. jae not_in_hi_rom
  3524. add eax, linHiROM
  3525. mov dx, ax
  3526. shr eax, 16
  3527. mov cx, ax
  3528. DPMICALL 0007h
  3529. not_in_hi_rom:
  3530. mov ax, bx
  3531. pop ds
  3532. UnsetKernelDS
  3533. pop dx
  3534. pop cx
  3535. pop bx
  3536. cEnd
  3537. ;-----------------------------------------------------------------------------
  3538. ;
  3539. ; ChangeROMHandle
  3540. ;
  3541. ;-----------------------------------------------------------------------------
  3542. assumes ds,nothing
  3543. assumes es,nothing
  3544. assumes fs,nothing
  3545. assumes gs,nothing
  3546. cProc ChangeROMHandle, <FAR, PUBLIC>, <si, bx, es, di, ds>
  3547. parmW hold
  3548. parmW hnew
  3549. localV dscbuf, DSC_LEN
  3550. cBegin
  3551. SetKernelDS
  3552. mov ds, ArenaSel
  3553. UnsetKernelDS
  3554. mov bx, hold
  3555. cCall get_arena_pointer32, <bx>
  3556. or eax, eax
  3557. jz short crh_bummer_dude
  3558. push eax
  3559. mov si, bx
  3560. and si, SEG_RING_MASK
  3561. or si, hnew
  3562. smov es, ss
  3563. lea di, dscbuf
  3564. DPMICALL 000Bh
  3565. xchg bx, si
  3566. DPMICALL 000Ch
  3567. cCall AssociateSelector32, <si, 0, 0>
  3568. pop eax
  3569. test dscbuf.dsc_access, DSC_PRESENT
  3570. jz short @F
  3571. mov ds:[eax].pga_handle, bx
  3572. @@:
  3573. cCall AssociateSelector32, <bx, eax>
  3574. cCall FreeSelArray, <hold>
  3575. mov ax, bx
  3576. crh_bummer_dude:
  3577. cEnd
  3578. ;-----------------------------------------------------------------------------
  3579. ;
  3580. ; CloneROMSelector
  3581. ;
  3582. ;-----------------------------------------------------------------------------
  3583. assumes ds,nothing
  3584. assumes es,nothing
  3585. assumes fs,nothing
  3586. assumes gs,nothing
  3587. cProc CloneROMSelector, <NEAR, PUBLIC>, <es, di, bx, ds>
  3588. parmW selROM
  3589. parmW selClone
  3590. cBegin
  3591. SetKernelDS
  3592. mov di, selROM
  3593. mov es, selROMTOC
  3594. assumes es, nothing
  3595. and di, NOT SEG_RING_MASK
  3596. sub di, es:[FirstROMSel]
  3597. mov es, selROMLDT
  3598. mov bx, selClone
  3599. DPMICALL 000Ch
  3600. cCall HocusROMBase, <bx>
  3601. mov ds, ArenaSel
  3602. cCall AssociateSelector32, <bx, 0, 0>
  3603. mov ax, bx
  3604. cEnd
  3605. ;-----------------------------------------------------------------------------
  3606. ;
  3607. ; Get/SetROMOwner
  3608. ;
  3609. ;-----------------------------------------------------------------------------
  3610. assumes ds,nothing
  3611. assumes es,nothing
  3612. assumes fs,nothing
  3613. assumes gs,nothing
  3614. cProc SetROMOwner, <NEAR, PUBLIC>, <ds, ebx, es>
  3615. parmW selector
  3616. parmW owner
  3617. cBegin
  3618. GENTER32
  3619. cCall AssociateSelector32, <selector, 0FFFFh, owner>
  3620. GLEAVE32
  3621. cEnd
  3622. cProc FarSetROMOwner, <FAR, PUBLIC>
  3623. parmW selector
  3624. parmW owner
  3625. cBegin
  3626. cCall SetROMOwner, <selector, owner>
  3627. cEnd
  3628. cProc GetROMOwner, <NEAR, PUBLIC>, <ds, es, ebx>
  3629. parmW selector
  3630. cBegin
  3631. UnsetKernelDS
  3632. SetKernelDS es
  3633. mov ds, ArenaSel
  3634. movzx ebx, selector
  3635. and bl, not SEG_RING_MASK
  3636. shr bx, 1
  3637. cmp bx, SelTableLen
  3638. jae short gro_nope
  3639. add ebx, SelTableStart
  3640. mov eax, ds:[ebx]
  3641. cmp eax, 0FFFF0000h
  3642. jae short gro_ok
  3643. gro_nope:
  3644. xor eax, eax
  3645. gro_ok:
  3646. cEnd
  3647. ;-----------------------------------------------------------------------------
  3648. ;
  3649. ; IsROMObject
  3650. ;
  3651. ;-----------------------------------------------------------------------------
  3652. assumes ds,nothing
  3653. assumes es,nothing
  3654. assumes fs,nothing
  3655. assumes gs,nothing
  3656. cProc IsROMObject, <NEAR, PUBLIC>, <bx, di, es>
  3657. parmW selector
  3658. localV DscBuf, DSC_LEN
  3659. cBegin
  3660. if KDEBUG
  3661. mov ax, selector
  3662. sel_check ax
  3663. endif
  3664. mov bx, selector
  3665. smov es, ss
  3666. lea di, DscBuf
  3667. DPMICALL 000Bh
  3668. SetKernelDS ES
  3669. mov ah, DscBuf.dsc_hbase
  3670. mov al, DscBuf.dsc_mbase
  3671. shl eax, 16
  3672. mov ax, DscBuf.dsc_lbase
  3673. sub eax, linHiROM
  3674. jc short iro_not_rom
  3675. sub eax, cbHiROM
  3676. jnc short iro_not_rom
  3677. mov al, 1
  3678. jmps iro_exit
  3679. iro_not_rom:
  3680. xor eax, eax
  3681. iro_exit:
  3682. cEnd
  3683. cProc FarIsROMObject, <FAR, PUBLIC>
  3684. parmW selector
  3685. cBegin
  3686. cCall IsROMObject, <selector>
  3687. cEnd
  3688. endif
  3689. ifdef WOW
  3690. ;-----------------------------------------------------------------------------
  3691. ; Grab the selector 0x47 so that we dont need to special case the biosdata
  3692. ; selector (0x40) while converting seg:off address to flat 32bit address
  3693. ;
  3694. ; This, however should not be part of Krnl286 heap.
  3695. ;
  3696. ; - Nanduri Ramakrishna
  3697. ;-----------------------------------------------------------------------------
  3698. cProc AllocSelector_0x47,<PUBLIC,FAR>, <ax, bx, cx, ds>
  3699. cBegin
  3700. ; alloc the specific selector
  3701. mov bx, 047h
  3702. DPMICALL 0dh
  3703. jc as47_exit
  3704. ; initialize the LDT
  3705. and bx, not SEG_RING
  3706. mov ds, gdtdsc
  3707. mov [bx].dsc_limit, 00h ; = 1 byte
  3708. mov [bx].dsc_lbase, 0400h
  3709. mov [bx].dsc_mbase, 00h
  3710. mov [bx].dsc_hbase, 00h
  3711. mov ax, DSC_DATA+DSC_PRESENT
  3712. and ah, not 0Fh ; Zero limit 19:16
  3713. mov word ptr [bx].dsc_access, ax
  3714. ; set the LDT
  3715. mov cx,1
  3716. mov bx, 047h
  3717. DPMICALL WOW_DPMIFUNC_0C
  3718. as47_exit:
  3719. cEnd
  3720. endif
  3721. sEnd CODE
  3722. sBegin NRESCODE
  3723. assumes CS,NRESCODE
  3724. assumes DS,NOTHING
  3725. assumes ES,NOTHING
  3726. ; All the code below is to support DIB.DRV and WING.
  3727. cProc get_sel_flags,<PUBLIC,FAR>
  3728. parmW selector
  3729. cBegin
  3730. SetKernelDSNRes
  3731. mov ds,pGlobalHeap
  3732. cCall far_get_arena_pointer32,<selector>
  3733. or eax,eax
  3734. jz gsf5
  3735. movzx ax, byte ptr ds:[eax].pga_flags
  3736. gsf5:
  3737. xor dx,dx
  3738. cEnd
  3739. cProc set_sel_for_dib,<PUBLIC,FAR>
  3740. parmW selector
  3741. parmW flags
  3742. parmW addressLo
  3743. parmW addressHi
  3744. parmW csel
  3745. cBegin
  3746. SetKernelDSNRes
  3747. push ecx
  3748. push ebx
  3749. push fs
  3750. push es
  3751. ; if the selector has a value of -1, it means we either need to allocate
  3752. ; or deallocate an array of selectors. If we are allocating, csel will have
  3753. ; a count of 64k selectors. If csel is 0, we need to deallocate the selector
  3754. ; array pointed to by address.
  3755. cmp selector,-1
  3756. jne ssfSetDIB
  3757. ; see if we are actually deleting the selector array
  3758. cmp csel,0
  3759. jne ssfAllocSel
  3760. ; free selector array at addressHi
  3761. cCall IFreeSelector,<addressHi>
  3762. mov ax,1
  3763. mov dx,0
  3764. jmp ssf5
  3765. ssfAllocSel:
  3766. ; we need to have the selector array created
  3767. cCall AllocSelectorArray,<csel>
  3768. mov selector,ax
  3769. xor dx,dx
  3770. cmp ax,0
  3771. je ssf5
  3772. ; we must set the limits in the selectors. Each selector
  3773. ; must have a limit in bytes for the remainder of the buffer. If there are
  3774. ; 3 selectors, the first will be 0x0002ffff, the second 0x0001ffff, the
  3775. ; third 0x0000ffff.
  3776. mov cx,csel
  3777. mov bx,selector
  3778. ssfSetLimit:
  3779. sub cx,1 ; 1 less each time
  3780. cCall SetSelectorLimit,<bx,cx,-1>
  3781. add bx,DSC_LEN ; advance to the next selector
  3782. cmp cx,0 ; see if we have any more selector to set
  3783. jne ssfSetLimit
  3784. mov dx,addressHi
  3785. mov ax,addressLo
  3786. push selector
  3787. call far_set_physical_address
  3788. mov ax,0 ; return the first selector
  3789. mov dx,selector
  3790. jmp ssf5
  3791. ssfSetDIB:
  3792. push ds
  3793. mov ds,pGlobalHeap
  3794. cCall far_get_arena_pointer32,<selector>
  3795. or eax,eax
  3796. jz ssf5
  3797. pop fs
  3798. push eax ; save arena ptr
  3799. cCall GrowHeapDib,<eax,addressHi,addressLo>
  3800. or eax,eax
  3801. jnz ssf0
  3802. pop eax
  3803. xor eax,eax
  3804. jmp ssf5
  3805. ssf0:
  3806. pop esi ; ds:esi is arena ptr
  3807. push eax ; save the new arena
  3808. xor edi,edi ; ds:edi is global heap info
  3809. cCall Free_Object2
  3810. mov dx,addressHi
  3811. mov ax,addressLo
  3812. cCall far_set_physical_address,<selector>
  3813. pop eax
  3814. push eax
  3815. cCall FarAssociateSelector32, <selector, eax>
  3816. ; now see that the GAH_PHANTOM flag is set in the arena
  3817. pop edx
  3818. or ds:[edx].pga_flags, GAH_PHANTOM
  3819. ; Now check if we are operating on a local heap. If so we change the
  3820. ; LocalNotifyDefault to LocalNotifyDib.
  3821. push es
  3822. push selector
  3823. pop es
  3824. xor edi,edi
  3825. mov di,word ptr es:[pLocalHeap]
  3826. or di,di
  3827. jz ssf4 ; Its not a local heap
  3828. cmp edi,ds:[edx].pga_size
  3829. jae ssf4 ; Its not a local heap
  3830. cmp word ptr es:[di].li_sig,LOCALHEAP_SIG ; es:li_sig == LH
  3831. jne ssf4
  3832. if KDEBUG
  3833. cmp word ptr es:[di].li_notify,codeOFFSET LocalNotifyDefault
  3834. jne ssf2
  3835. cmp word ptr es:[di].li_notify+2,codeBase
  3836. je ssf3
  3837. ssf2:
  3838. krDebugOut <DEB_TRACE OR DEB_KrMemMan>, "Set_Sel_For_Dib: App has hooked LocalNotifyDefault"
  3839. ssf3:
  3840. endif
  3841. mov word ptr es:[di].li_notify,codeOFFSET LocalNotifyDib
  3842. mov word ptr es:[di].li_notify+2,codeBase
  3843. ssf4:
  3844. pop es
  3845. mov eax,1
  3846. ssf5:
  3847. pop es
  3848. pop fs
  3849. pop ebx
  3850. pop ecx
  3851. cEnd
  3852. cProc RestoreDib,<PUBLIC,FAR>
  3853. parmW selector
  3854. parmW flags
  3855. parmD address
  3856. localw hNewDib
  3857. localw cSel
  3858. localD DibSize
  3859. localD NewArena
  3860. localD OldArena
  3861. cBegin
  3862. SetKernelDSNRes
  3863. push ecx
  3864. push ebx
  3865. push fs
  3866. push es
  3867. ;; Allocate a new global block
  3868. xor eax, eax ; In case lsl fails
  3869. lsl eax, dword ptr selector
  3870. or eax,eax
  3871. jz rd_fail
  3872. inc eax
  3873. mov DibSize,eax
  3874. cCall IGlobalAlloc,<flags,eax>
  3875. or ax,ax
  3876. jz rd_fail
  3877. mov hNewDib,ax
  3878. push ds
  3879. pop fs
  3880. mov ds,pGlobalHeap
  3881. cCall far_get_arena_pointer32,<selector>
  3882. mov OldArena,eax
  3883. or eax,eax
  3884. jz rd2
  3885. movzx ax, word ptr [eax].pga_selcount
  3886. mov cSel,ax
  3887. cCall far_get_arena_pointer32,<hNewDib>
  3888. or eax,eax
  3889. jnz rd5
  3890. rd2:
  3891. cCall IGlobalFree,<hNewDib>
  3892. jmp rd_fail
  3893. rd5:
  3894. mov NewArena,eax
  3895. cld
  3896. push ds
  3897. mov ecx,DibSize
  3898. mov ax, hNewDib
  3899. or ax, 1
  3900. mov es, ax
  3901. mov ds, selector
  3902. xor esi, esi
  3903. xor edi, edi
  3904. mov eax,ecx
  3905. shr ecx,2 ; dwords
  3906. rep movs dword ptr es:[edi], dword ptr ds:[esi]
  3907. and eax,3
  3908. mov ecx,eax
  3909. rep movs byte ptr es:[edi], byte ptr ds:[esi]
  3910. pop ds
  3911. ;; free the selector that came back with GlobalAlloc
  3912. xor eax,eax
  3913. cCall farAssociateSelector32, <hNewDib,eax>
  3914. cCall IFreeSelector, <hNewDib>
  3915. ;; Map the original selector to this new block
  3916. mov eax,NewArena
  3917. mov edx,[eax].pga_address
  3918. mov ebx,[eax].pga_size
  3919. dec ebx
  3920. mov ax,dx
  3921. shr edx,16
  3922. cCall far_set_physical_address,<selector>
  3923. mov eax,NewArena
  3924. cCall farAssociateSelector32, <selector,eax>
  3925. mov cx,cSel
  3926. mov dx,selector
  3927. rd13:
  3928. dec cx
  3929. push bx
  3930. push cx
  3931. push dx
  3932. cCall SetSelectorLimit,<dx,cx,bx>
  3933. pop dx
  3934. pop cx
  3935. pop bx
  3936. add dx,DSC_LEN ; advance to the next selector
  3937. jcxz rd14
  3938. jmp short rd13
  3939. rd14:
  3940. ;; Fix some values in the new arena from old arena
  3941. mov eax,NewArena
  3942. mov ebx,OldArena
  3943. mov ecx,dword ptr [ebx].pga_handle
  3944. mov dword ptr [eax].pga_handle,ecx
  3945. mov ecx,dword ptr [ebx].pga_count
  3946. dec ecx
  3947. mov dword ptr [eax].pga_count,ecx
  3948. and byte ptr [eax].pga_flags, NOT GAH_PHANTOM
  3949. ;; Free the dib
  3950. cCall FreeHeapDib, <OldArena>
  3951. ; Now check if we are operating on a local heap. If we so change the
  3952. ; LocalNotifyDiB to LocalNotify.
  3953. mov edx, NewArena
  3954. push selector
  3955. pop es
  3956. xor edi,edi
  3957. mov di,word ptr es:[pLocalHeap]
  3958. or di,di
  3959. jz rd_15
  3960. cmp edi,ds:[edx].pga_size
  3961. jae rd_15 ; Its not a local heap
  3962. cmp word ptr es:[di].li_sig,LOCALHEAP_SIG ; es:li_sig == LH
  3963. jne rd_15
  3964. mov word ptr es:[di].li_notify,codeOFFSET LocalNotifyDefault
  3965. mov word ptr es:[di].li_notify+2,codeBase
  3966. rd_15:
  3967. mov eax,1
  3968. jmp short rd_exit
  3969. rd_fail:
  3970. xor eax,eax
  3971. rd_exit:
  3972. pop es
  3973. pop fs
  3974. pop ebx
  3975. pop ecx
  3976. cEnd
  3977. cProc DibRealloc,<PUBLIC,FAR>
  3978. parmW Selector
  3979. parmW NewSize
  3980. cBegin
  3981. SetKernelDSNRes
  3982. push ebx
  3983. mov ds,pGlobalHeap
  3984. cCall far_get_arena_pointer32,<Selector>
  3985. or eax,eax
  3986. jz dr20
  3987. movzx ebx,NewSize
  3988. mov ds:[eax].pga_size,bx
  3989. add ebx,ds:[eax].pga_address
  3990. mov eax,ds:[eax].pga_next
  3991. mov dword ptr ds:[eax].pga_address,ebx
  3992. mov bx,NewSize
  3993. dec bx
  3994. cCall SetSelectorLimit,<Selector,0,bx>
  3995. mov ax,Selector
  3996. jmp short drexit
  3997. dr20:
  3998. xor ax,ax
  3999. drexit:
  4000. pop ebx
  4001. cEnd
  4002. sEnd NRESCODE
  4003. end
  4004.