Leaked source code of windows server 2003
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.

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