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.

1054 lines
33 KiB

  1. TITLE LDAUX - Assembler side of LD.C
  2. .xlist
  3. include kernel.inc
  4. include newexe.inc
  5. include tdb.inc
  6. include protect.inc
  7. .list
  8. DataBegin
  9. externB fChksum
  10. externW hExeHead
  11. externW curTDB
  12. externW PHTcount
  13. externW kr1dsc
  14. szFake32BitModuleName DB 128 DUP(0)
  15. cFake32BitModuleName DW SIZE szFake32BitModuleName
  16. ifdef WOW
  17. szWinGDllModule DB 'WING', 0
  18. szWinGDllFile DB '\SYSTEM\WING.DLL',0
  19. externD lpWindowsDir
  20. externW cBytesWinDir
  21. endif ; WOW
  22. ifdef DBCS_KEEP
  23. ifdef WOW
  24. public hModNotepad
  25. hModNotepad DW 0
  26. NotepadName DB 'notepad.exe', 0
  27. endif ; WOW
  28. endif ; DBCS_KEEP
  29. DataEnd
  30. externFP GlobalAlloc
  31. externFP GlobalFree
  32. externFP GlobalHandle
  33. externFP GetExePtr
  34. externFP FarMyUpper
  35. externFP FarFindOrdinal
  36. externFP FarEntProcAddress
  37. externFP FarMyLock
  38. externFP FarGetOwner
  39. externFP AllocSelector
  40. externFP IPrestoChangoSelector
  41. externFP FreeSelector
  42. externFP lstrcpyn
  43. ifdef WOW
  44. ifdef DBCS_KEEP
  45. externFP WowGetModuleUsage
  46. externFP MyGetAppWOWCompatFlags
  47. endif ; DBCS_KEEP
  48. externFP WowGetModuleFileName
  49. externFP HandleAbortProc
  50. externFP WowGetModuleHandle
  51. endif
  52. ifdef FE_SB
  53. externFP FarMyIsDBCSLeadByte
  54. endif
  55. sBegin CODE
  56. assumes CS,CODE
  57. externNP LoadSegment
  58. externNP MyLock
  59. externNP GetOwner
  60. if LDCHKSUM
  61. externNP GetChksumAddr
  62. endif
  63. ;-----------------------------------------------------------------------;
  64. ; GetSegPtr ;
  65. ; ;
  66. ; ;
  67. ; Arguments: ;
  68. ; DS:SI = FARPROC or DS = hModule and SI = segment# ;
  69. ; ;
  70. ; Returns: ;
  71. ; BX = 0 ;
  72. ; CX = segment# or zero if input invalid ;
  73. ; DS:SI -> segment table entry ;
  74. ; ;
  75. ; Error Returns: ;
  76. ; ;
  77. ; Registers Preserved: ;
  78. ; ;
  79. ; Registers Destroyed: ;
  80. ; ;
  81. ; Calls: ;
  82. ; ;
  83. ; History: ;
  84. ; ;
  85. ; Sun 24-Dec-1989 22:49:50 -by- David N. Weise [davidw] ;
  86. ; Added check for MPI thunk. ;
  87. ; ;
  88. ; Wed Oct 07, 1987 12:59:54p -by- David N. Weise [davidw] ;
  89. ; Added this nifty comment block. ;
  90. ;-----------------------------------------------------------------------;
  91. assumes ds, nothing
  92. assumes es, nothing
  93. cProc GetSegPtr,<PUBLIC,NEAR>
  94. cBegin nogen
  95. xor bx,bx ; For cheap indexed addressing
  96. cmp ds:[bx].ne_magic,NEMAGIC; Is this a thunk address?
  97. jne gspFixed ; No, must be fixed procedure
  98. dec si ; No, see if valid segment #
  99. cmp si,ds:[bx].ne_cseg
  100. jb @F
  101. jmps gspfail ; No, fail
  102. @@: mov cx,si ; Yes, load that segment
  103. inc cx
  104. jmps gspSegNo
  105. ; CX = segment number. Convert to segment info pointer.
  106. gspSegNo:
  107. push cx
  108. dec cx
  109. shl cx,1
  110. mov si,cx
  111. shl cx,1
  112. shl cx,1
  113. add si,cx
  114. .errnz 10 - SIZE NEW_SEG1
  115. add si,ds:[bx].ne_segtab
  116. pop cx
  117. jmps gspExit ; DS:SI -> segment info block
  118. gspFixed: ; DS = code segment address
  119. ; check for MakeProcInstance thunk first because GetOwner in 386pmode
  120. ; ain't robust enough
  121. cmp byte ptr ds:[si].0,0B8h ; Maybe, is this a mov ax,XXXX inst?
  122. jnz gsp_not_mpit
  123. cmp byte ptr ds:[si].3,0EAh ; Followed by far jump inst?
  124. jnz gsp_not_mpit
  125. cmp ds:[2],MPIT_SIGNATURE ; Is it in a mpi table?
  126. jz gsp_yes_mpit
  127. cmp ds:[TDB_MPI_THUNKS].2,MPIT_SIGNATURE
  128. jnz gsp_not_mpit
  129. gsp_yes_mpit:
  130. lds si,ds:[si].4 ; get real procedure address
  131. jmp GetSegPtr
  132. gsp_not_mpit:
  133. push ax
  134. mov dx, ds ; Handle in dx
  135. StoH dl ; Assume not fixed
  136. cCall GetOwner,<ds>
  137. or ax,ax
  138. mov ds, ax
  139. pop ax
  140. jz gspfail
  141. gspf1:
  142. cmp ds:[bx].ne_magic,NEMAGIC; Is it a module DB?
  143. jnz gspfail ; Nope, fail.
  144. getting_closer:
  145. mov si,ds:[bx].ne_segtab ; Yes, point to segment table
  146. mov cx,ds:[bx].ne_cseg
  147. gspLoop:
  148. cmp dx,ds:[si].ns_handle ; Scan stmen
  149. jz gspFound
  150. HtoS dx ; May be fixed seg???
  151. cmp dx,ds:[si].ns_handle ; Scan stmen
  152. jz gspFound
  153. StoH dx
  154. add si,SIZE NEW_SEG1
  155. loop gspLoop
  156. gspfail:
  157. xor cx,cx
  158. jmps gspExit
  159. gspFound:
  160. sub cx,ds:[bx].ne_cseg ; Compute segment# from remainder
  161. neg cx ; of loop count
  162. inc cx ; 1-based segment#
  163. gspExit:
  164. ret
  165. cEnd nogen
  166. assumes ds, nothing
  167. assumes es, nothing
  168. cProc IGetCodeInfo,<PUBLIC,FAR>,<si,di>
  169. parmD lpProc
  170. parmD lpSegInfo
  171. cBegin
  172. lds si,lpProc
  173. call getsegptr
  174. mov ax,cx
  175. jcxz gciExit
  176. les di,lpSegInfo
  177. mov cx,SIZE NEW_SEG1
  178. cld
  179. rep movsb
  180. mov ax,ds:[bx].ne_align ; Return segment aligment
  181. stosw
  182. sub si,SIZE NEW_SEG1
  183. sub di,SIZE NEW_SEG1+2
  184. cmp si,ds:[bx].ne_pautodata
  185. jne gciExit
  186. mov ax,ds:[bx].ne_stack
  187. add ax,ds:[bx].ne_heap
  188. add es:[di].ns_minalloc,ax
  189. gciExit:
  190. smov es,ds ; put module handle (returned from getsegptr) into es
  191. ; user depends on this
  192. mov cx,ax ; WHY IS THIS HERE?
  193. ;
  194. ; NOTE: USER assumes that AX == BOOL fSuccess and ES == hModule upon return
  195. ;
  196. cEnd
  197. assumes ds, nothing
  198. assumes es, nothing
  199. cProc GetCodeHandle,<PUBLIC,FAR>,<si,di>
  200. parmD lpProc
  201. cBegin
  202. lds si,lpProc
  203. call getsegptr
  204. mov dx,cx
  205. jcxz gchExit
  206. mov ax,ds:[si].ns_handle
  207. ; test ds:[si].ns_flags,NSLOADED
  208. ; jnz gchExit
  209. mov dx,-1
  210. cCall LoadSegment,<ds,cx,dx,dx>
  211. cCall MyLock,<ax>
  212. xchg ax,dx
  213. cmp ax,dx
  214. je gchExit
  215. ; %OUT Need pmode lru stuff here
  216. gchExit:
  217. cEnd
  218. assumes ds,nothing
  219. assumes es,nothing
  220. cProc CallProcInstance,<PUBLIC,FAR>
  221. cBegin nogen
  222. mov ax,ds ; AX = caller's DS
  223. mov cx,es:[bx] ; CX = hInstance
  224. jcxz cpx ; If zero, then use caller's DS
  225. xchg ax,cx ; AX = hInstance, CX = caller's DS
  226. test al,GA_FIXED ; Fixed?
  227. jnz cpx ; Yes, all set
  228. xchg bx,ax ; No, BX = hInstance, ES:AX ->
  229. labelFP <PUBLIC,CallMoveableInstanceProc> ; procedure address.
  230. HtoS bx ; Get selector
  231. xchg bx,ax ; AX = segment address
  232. mov ds,cx ; Restore DS
  233. cpx: jmp dword ptr es:[bx][2] ; Jump to far procedure
  234. cEnd nogen
  235. sEnd CODE
  236. sBegin NRESCODE
  237. assumes CS,NRESCODE
  238. externNP MapDStoDATA
  239. externNP FindExeInfo
  240. externNP FindExeFile
  241. externNP NResGetPureName
  242. assumes ds,nothing
  243. assumes es,nothing
  244. cProc CopyName,<PUBLIC,NEAR>,<si>
  245. parmD pname
  246. parmW pdst
  247. parmW fUpper
  248. cBegin
  249. les si,pname
  250. mov bx,pdst
  251. mov cx,127
  252. mov dx,fUpper
  253. cn0:
  254. lods byte ptr es:[si]
  255. or al,al
  256. jz cn1
  257. or dx,dx
  258. jz cn0a
  259. ifdef FE_SB
  260. call FarMyIsDBCSLeadByte ; test if a char is lead byte of DBC
  261. jc @F ; jump if not a DBC
  262. inc bx
  263. mov ss:[bx],al ; store first byte of DBC
  264. dec cx
  265. jcxz cn1 ; pay attention for counter exhaust...
  266. lods byte ptr es:[si] ; fetch a 2nd byte of DBC
  267. jmps cn0a
  268. @@:
  269. endif
  270. call FarMyUpper
  271. cn0a:
  272. inc bx
  273. mov ss:[bx],al
  274. loop cn0
  275. cn1:
  276. mov byte ptr ss:[bx+1],0
  277. mov ax,bx
  278. mov bx,pdst
  279. sub ax,bx
  280. mov ss:[bx],al
  281. cEnd
  282. assumes ds,nothing
  283. assumes es,nothing
  284. cProc IGetProcAddress,<PUBLIC,FAR>,<ds,si>
  285. parmW hinstance
  286. parmD pname
  287. localV namebuf,130
  288. cBegin
  289. mov cx,hinstance
  290. jcxz use_current_module
  291. cCall GetExePtr,<cx>
  292. xor dx,dx
  293. jcxz gpdone1
  294. mov si,ax
  295. mov es,ax
  296. test es:[ne_flags],NENOTP
  297. jnz have_module_address
  298. xor bx,bx
  299. if KDEBUG
  300. fkerror 00FFh,<Can not GetProcAddress a task.>,es,bx
  301. endif
  302. xor ax,ax
  303. xor dx,dx
  304. gpdone1:
  305. jmps gpdone
  306. use_current_module:
  307. cCall MapDStoDATA
  308. ReSetKernelDS
  309. mov es,curTDB
  310. UnSetKernelDS
  311. mov si,es:[TDB_pModule]
  312. have_module_address:
  313. cmp seg_pname,0
  314. jne gp0
  315. mov ax,off_pname
  316. jmps gpaddr
  317. gp0:
  318. lea bx,namebuf
  319. xor dx,dx
  320. cCall CopyName,<pname,bx,dx>
  321. lea bx,namebuf
  322. mov dx,-1
  323. cCall FarFindOrdinal,<si,ssbx,dx>
  324. cwd ; set DX to 0 if no ordinal
  325. or ax,ax
  326. jz gpdone ; if no ordinal, leave with 0:0
  327. gpaddr:
  328. cCall FarEntProcAddress,<si,ax>
  329. gpdone:
  330. mov cx,ax
  331. or cx,dx
  332. cEnd
  333. ;-----------------------------------------------------------------------;
  334. ; GetModuleHandle
  335. ;
  336. ; Returns the module handle, AKA segment address, of the named
  337. ; module. The pname should be a pointer to a name, however
  338. ; because we want FreeFontResource to take a file name we check
  339. ; for that one special case for file names.
  340. ;
  341. ; Entry:
  342. ; parmW pname
  343. ; or 0:instance handle
  344. ; Returns:
  345. ; AX = handle if loaded
  346. ; = 0 if not loaded
  347. ;
  348. ; Registers Destroyed:
  349. ; BX,CX,DX,ES
  350. ;
  351. ; History:
  352. ; Sat 18-Nov-1989 21:57:24 -by- David N. Weise [davidw]
  353. ; Adding the handling of exeheaders above the line by calling
  354. ; off to EMS_GetModuleHandle. A little while ago is when
  355. ; the checking for filenames was added.
  356. ;
  357. ; Tue 04-Apr-1989 01:42:12 -by- David N. Weise [davidw]
  358. ; This used to return DX = ExeHead, this is now returned in CX.
  359. ;
  360. ; Tue 28-Mar-1989 17:28:34 -by- David N. Weise [davidw]
  361. ; Put in the Excel hack and added this nifty comment block.
  362. ;-----------------------------------------------------------------------;
  363. assumes ds,nothing
  364. assumes es,nothing
  365. cProc IGetModuleHandle,<PUBLIC,FAR>,<di,si>
  366. parmD pname
  367. localV nameBuf,130
  368. cBegin
  369. cCall MapDStoDATA
  370. ReSetKernelDS
  371. cmp pname.sel,0
  372. ifndef DBCS_KEEP
  373. jz gm1
  374. else ; DBCS_KEEP
  375. ifdef WOW
  376. jnz gm_chk
  377. jmp gm1
  378. for Lotus Freelance Instration program
  379. gm_chk:
  380. call MyGetAppWOWCompatFlags
  381. test ax, 4 ; WOWCF_AUDITNOTEPAD
  382. jz gm_ne
  383. lea si,NotepadName
  384. les di,pname
  385. mov cx,11
  386. cmpsb
  387. jnz gm_ne
  388. mov ax,hModNotepad
  389. or ax,ax
  390. jz gm_ne
  391. cmp ax,1
  392. jnz gm_pe
  393. mov bx,10
  394. xor cx,cx
  395. cCall GlobalAlloc,<cx,cx,bx>
  396. or ax,ax
  397. jz gm_hdl
  398. mov hModNotepad,ax
  399. gm_pe:
  400. jmp short gmexit
  401. gm_ne:
  402. endif ; WOW
  403. endif ; DBCS_KEEP
  404. lea di,namebuf
  405. xor dx,dx ; Try as is first
  406. cCall CopyName,<pname,di,dx>
  407. inc di ; point past count
  408. push ax
  409. cCall FindExeInfo,<ss,di,ax>
  410. pop bx
  411. or ax,ax
  412. jnz gmexit
  413. lea di,namebuf
  414. mov dx,-1 ; Now force upper case
  415. cCall CopyName,<pname,di,dx>
  416. inc di ; point past count
  417. push ax
  418. cCall FindExeInfo,<ss,di,ax>
  419. pop bx
  420. or ax,ax
  421. jnz gmexit
  422. smov es,ss
  423. call NResGetPureName
  424. cCall FindExeFile,<ss,di>
  425. jmps gmexit
  426. gm1: cCall GetExePtr,<OFF_pname>
  427. gmexit:
  428. ifdef WOW
  429. ;
  430. ; If we didn't find a matching module, call WOW32 to see if
  431. ; the module name matches the module name of a child app
  432. ; spawned via WinOldAp. If it does, WOW32 will return
  433. ; that WinOldAp's hmodule. If not, WOW32 will return zero.
  434. ;
  435. or ax,ax
  436. jnz @F
  437. lea di,namebuf[1]
  438. cCall WowGetModuleHandle, <ss,di>
  439. @@:
  440. endif
  441. mov dx,hExeHead ; return this as a freebie
  442. cEnd
  443. assumes ds,nothing
  444. assumes es,nothing
  445. cProc IGetModuleName,<PUBLIC,FAR>,<si,di>
  446. parmW hinstance
  447. parmD lpname
  448. parmW nbytes
  449. cBegin
  450. mov ax, nbytes
  451. or ax, ax
  452. jnz @f
  453. jmp gfx
  454. @@: cCall GetExePtr,<hinstance>
  455. or ax,ax
  456. jz gmn
  457. mov ds,ax
  458. mov si,ds:[ne_restab] ; Module name is first entry in Res Name Table
  459. xor cx,cx
  460. mov cl,ds:[si] ; Get Len of module name
  461. inc cl ; Space for NULL
  462. inc si ; Goto start of module name
  463. cmp cx,nbytes
  464. jl gmn1
  465. mov cx,nbytes
  466. gmn1:
  467. push lpname
  468. push ds
  469. push si
  470. push cx
  471. call lstrcpyn
  472. mov ax,0DDh ; Return a true value
  473. gmn:
  474. cEnd
  475. ;-----------------------------------------------------------------------
  476. ; IsWingModule
  477. ; Checks if GetModuleFileHandle is called by Wing.dll
  478. ; on itself.
  479. ; and fills lpname if it is so
  480. ;
  481. ; Arguments:
  482. ; hinstance - GetModuleFileName's hinstance arg
  483. ; lpname - GetModuleFileName's lpname arg
  484. ; nbytes - GetModuleFileName's lpname arg
  485. ; exehdr - ExeHdr of hinstance
  486. ; rcsel - Return Code Selector that called GMFH
  487. ; Returns:
  488. ; AX = number of bytes copied if wing is calling GetModuleFileName on itself
  489. ; AX = 0 otherwise
  490. ;
  491. ;------------------------------------------------------------------------
  492. cProc IsWingModule,<PUBLIC,FAR>,<si,di,ds,es>
  493. parmW hinstance
  494. parmD lpname
  495. parmW nbytes
  496. parmW exehdr
  497. parmW rcsel
  498. cBegin
  499. mov es,exehdr
  500. mov di,es:[ne_restab]
  501. inc di ;got modulename
  502. cCall MapDStoDATA
  503. assumes DS, DATA
  504. lea si, szWinGDllModule
  505. mov cx,5
  506. repe cmpsb
  507. jnz short IWM_NoMatch
  508. cCall getexeptr,<rcsel>
  509. cmp ax,exehdr
  510. jnz short IWM_NoMatch
  511. mov cx, cBytesWinDir
  512. add cx, 17 ;17=strlen("\system\wing.dll")+1;
  513. cmp cx,nbytes
  514. ja short IWM_NoMatch ;return righ away if doesn't fit
  515. mov ax,cx
  516. sub cx,17
  517. les di,lpname
  518. lds si,lpWindowsDir
  519. cld
  520. rep movsb
  521. mov cx,17
  522. lea si,szWinGDllFile
  523. rep movsb
  524. jmp short IWM_End
  525. IWM_NoMatch:
  526. mov ax,0
  527. IWM_End:
  528. cEnd
  529. ;
  530. ;NOTE: BX preserved because Actor 4.0 depends on this (bug 9078 - neilk)
  531. ;
  532. cProc IGetModuleFileName,<PUBLIC,FAR>,<si,di,bx>
  533. parmW hinstance
  534. parmD lpname
  535. parmW nbytes
  536. cBegin
  537. ifdef WOW
  538. ; take care of 32bit hInstance. 32bit hInstance has GDT/LDT bit clear
  539. ; the validation layer will pass such handles as valid so that we can
  540. ; thunk to 32bit GetModuleFileName if needed.
  541. ;
  542. ; in win32 hInstances are not global. therefore fake success by
  543. ; returning a valid module name for compatibility sake. Naturally,
  544. ; we will use our module name.
  545. mov ax, hInstance
  546. test al, 0100b ; Check for task aliases (see WOLE2.C) or BOGUSGDT
  547. jnz GMFName_Normal
  548. or ax, ax
  549. jz GMFName_Normal
  550. cCall MapDStoDATA
  551. assumes DS, DATA
  552. mov cx, cFake32BitModuleName
  553. lea si, szFake32BitModuleName
  554. cCall WowGetModuleFileName, <ax, ds, si, cx>
  555. mov cx,ax
  556. jmps GMF_CopyName32
  557. GMFName_Normal:
  558. endif
  559. mov ax, nbytes
  560. or ax, ax
  561. jz gfx
  562. cCall GetExePtr,<hinstance>
  563. or ax,ax
  564. jz gfx
  565. mov ds,ax
  566. cCall IsWinGModule,<hinstance,lpname,nbytes,ax,[bp+4]>
  567. or ax, ax
  568. jnz gfx
  569. mov si,ds:[ne_pfileinfo]
  570. xor cx,cx
  571. mov cl,ds:[si].opLen
  572. sub cx,opFile
  573. lea si,[si].opFile
  574. ifdef WOW
  575. GMF_CopyName32:
  576. endif
  577. les di,lpname
  578. cmp cx,nbytes
  579. jl gf1
  580. mov cx,nbytes
  581. dec cx
  582. gf1:
  583. cld
  584. mov ax,cx
  585. rep movsb
  586. mov es:[di],cl
  587. gfx:
  588. mov cx,ax
  589. ;** Nasty hack to support QuickWin libs (Fortran, QCWin)
  590. ;** The startup code assumes DX will be the segment of the
  591. ;** lpname parameter
  592. mov dx,WORD PTR lpname[2]
  593. cEnd
  594. assumes ds,nothing
  595. assumes es,nothing
  596. cProc IGetModuleUsage,<PUBLIC,FAR>
  597. parmW hinstance
  598. cBegin
  599. ifdef DBCS_KEEP
  600. ifdef WOW
  601. cCall MapDStoDATA
  602. ReSetKernelDS
  603. call MyGetAppWOWCompatFlags
  604. test ax, 4 ; WOWCF_AUDITNOTEPAD
  605. jz gu_ne
  606. mov ax,hModNotepad
  607. or ax,ax
  608. jz gu_ne
  609. cmp ax,hinstance
  610. jnz gu_ne
  611. push ax
  612. cCall WowGetModuleUsage, <0>
  613. or ax,ax
  614. pop bx
  615. jnz gux
  616. cCall GlobalFree,<bx>
  617. jmp short gux
  618. gu_ne:
  619. endif ; WOW
  620. endif ; DBCS_KEEP
  621. cCall GetExePtr,<hinstance>
  622. or ax,ax
  623. jz gux
  624. got_one:
  625. mov es,ax
  626. mov ax,es:[ne_usage]
  627. gux: mov cx,ax
  628. cEnd
  629. assumes ds,nothing
  630. assumes es,nothing
  631. cProc IGetInstanceData,<PUBLIC,FAR>,<si,di>
  632. parmW hinstance
  633. parmW psrcdst
  634. parmW nbytes
  635. cBegin
  636. push ds
  637. cCall GlobalHandle,<hinstance>
  638. pop es ; Get caller's DS as destination
  639. or dx,dx
  640. jz gidone
  641. mov ds,dx ; Source is passed instance
  642. mov si,psrcdst ; Offsets are the same
  643. mov di,si
  644. mov ax,nbytes
  645. mov cx,ax
  646. jcxz gidone
  647. cld
  648. rep movsb
  649. push es
  650. pop ds
  651. gidone: mov cx,ax
  652. cEnd
  653. sEnd NRESCODE
  654. sBegin MISCCODE
  655. assumes cs, misccode
  656. assumes ds, nothing
  657. assumes es, nothing
  658. externNP MISCMapDStoDATA
  659. ;-----------------------------------------------------------------------;
  660. ; MakeProcInstance ;
  661. ; ;
  662. ; Cons together a far procedure address with a data segment address, ;
  663. ; in the form ;
  664. ; ;
  665. ; mov ax,DGROUP ;
  666. ; jmp far pproc ;
  667. ; ;
  668. ; This procedure allocates a fixed segment for a set of thunks and ;
  669. ; threads the thunks together on a free list within the segment. ;
  670. ; When a thunk segment is full, a new one is allocated and pushed ;
  671. ; onto the head of the list of thunk segments pointed to by ;
  672. ; TDB_MPI_Thunks. ;
  673. ; ;
  674. ; Arguments: ;
  675. ; parmD pproc ;
  676. ; parmW hinstance ;
  677. ; ;
  678. ; Returns: ;
  679. ; DX:AX = ProcInstance ;
  680. ; CX != 0 ;
  681. ; ;
  682. ; Error Returns: ;
  683. ; DX:AX = NULL ;
  684. ; CX = 0 ;
  685. ; ;
  686. ; Registers Preserved: ;
  687. ; DI,SI,DS ;
  688. ; ;
  689. ; Registers Destroyed: ;
  690. ; BX,ES ;
  691. ; ;
  692. ; Calls: ;
  693. ; MapDStoDATA ;
  694. ; GlobalAlloc ;
  695. ; FarMyLock ;
  696. ; ;
  697. ; History: ;
  698. ; ;
  699. ; Sat Sep 26, 1987 12:53:58p -by- David N. Weise [davidw] ;
  700. ; ReWrote it a while ago to work with EMS. ;
  701. ;-----------------------------------------------------------------------;
  702. assumes ds,nothing
  703. assumes es,nothing
  704. cProc IMakeProcInstance,<PUBLIC,FAR>,<si,di>
  705. parmD pproc
  706. parmW hinstance
  707. cBegin
  708. SetKernelDSMisc
  709. ; We try to prohibit tasks from calling into each other.
  710. ; One way to do this is to not allow one app to MPI for
  711. ; another.
  712. mov bx,[bp-2] ; Warning - assume DS pushed here!
  713. mov ax,hinstance ; if hInstance == NULL,
  714. or ax,ax ; use caller's DS
  715. jz mpi1
  716. push bx
  717. cCall GlobalHandle,<ax>
  718. pop bx
  719. cmp dx,bx
  720. jz mpi1
  721. xor cx,cx
  722. krDebugOut DEB_ERROR, "%dx2 MakeProcInstance only for current instance. "
  723. mpi1: mov hinstance,bx
  724. ; If this is a library DS then it makes absolutely no sense to make a
  725. ; ProcInstance because library prologs setup DS already! In addition
  726. ; it is assumed in TestDSAX that only task DS's are in ProcInstances.
  727. cCall FarGetOwner,<bx>
  728. mov es, ax
  729. NE_check_ES
  730. mov dx,pproc.sel
  731. mov ax,pproc.off
  732. test es:[ne_flags],NENOTP
  733. jz @F
  734. jmp mpexit ; It's a library - return its address
  735. @@:
  736. ; now try to get a thunklet
  737. mov ax,curTDB
  738. mov si,TDB_MPI_Thunks
  739. mov es,ax
  740. mov ax,es:[TDB_MPI_Sel]
  741. mp2: mov es,ax
  742. mov bx,es:[si].THUNKSIZE-2
  743. or bx,bx
  744. jz @F
  745. jmp got_a_thunk
  746. @@: mov ax,es:[si] ; Is there another block linked in?
  747. xor si,si
  748. or ax,ax
  749. jnz mp2 ; Yes, look at it.
  750. ; No thunks available, make a block.
  751. mov bx,THUNKSIZE * THUNKELEM
  752. mov cx,GA_ZEROINIT
  753. cCall GlobalAlloc,<cx,ax,bx>
  754. or ax,ax
  755. ; jnz mpx
  756. ; cwd
  757. jz mpfail
  758. ;mpx:
  759. mov bx,ax
  760. mov es,curTDB
  761. xchg es:[TDB_MPI_Thunks],bx ; Link the new block in.
  762. mov es,ax
  763. ; Initialize the new block.
  764. mov es:[0],bx
  765. mov es:[2],MPIT_SIGNATURE
  766. mov bx,THUNKSIZE-2
  767. mov cx,THUNKELEM-1
  768. mp1: lea dx,[bx+THUNKSIZE]
  769. .errnz THUNKELEM and 0FF00h
  770. mov es:[bx],dx
  771. mov bx,dx
  772. loop mp1
  773. mov es:[bx],cx
  774. push es ; make the block into a code segment
  775. cCall AllocSelector,<es>
  776. pop es
  777. or ax, ax
  778. jnz @F
  779. ; AllocSelector Failed! Back out.
  780. mov bx, es:[0] ; this is the old thunk val
  781. mov ax, es ; this is the segment just allocated
  782. mov es, curTDB
  783. mov es:[TDB_MPI_Thunks], bx ; restore old value
  784. cCall GlobalFree,<ax>
  785. mpfail:
  786. krDebugOut DEB_IERROR, "MakeProcInstance failed. Did you check return values?"
  787. xor ax, ax
  788. cwd
  789. jmps mpexit
  790. @@: mov di,ax
  791. push es
  792. cCall IPrestoChangoSelector,<di,es>
  793. cCall FreeSelector,<di>
  794. pop ax
  795. xor bx,bx
  796. jmp mp2
  797. got_a_thunk:
  798. push es
  799. ; we need a data alias so we can write into this thing
  800. push bx
  801. mov bx, kr1dsc
  802. or bl, SEG_RING
  803. cCall IPrestoChangoSelector,<es,bx>
  804. mov es,ax
  805. pop bx
  806. mov ax,es:[bx]
  807. mov es:[si].THUNKSIZE-2,ax
  808. lea di,[bx-THUNKSIZE+2]
  809. cld
  810. mov dx,di ; save offset of thunk
  811. mov al,0B8h ; mov ax,#
  812. stosb
  813. mov ax,hInstance
  814. stosw
  815. mov al,0EAh ; jmp far seg:off
  816. stosb
  817. mov ax,pproc.off
  818. stosw
  819. mov ax,pproc.sel
  820. stosw
  821. mov ax,dx ; recover offset of thunk
  822. pop dx ; recover sel of thunk
  823. mpexit:
  824. mov cx,ax
  825. or cx,dx
  826. cEnd
  827. ;-----------------------------------------------------------------------;
  828. ; FreeProcInstance ;
  829. ; ;
  830. ; Frees the given ProcInstance. ;
  831. ; ;
  832. ; Arguments: ;
  833. ; parmD pproc ;
  834. ; ;
  835. ; Returns: ;
  836. ; AX != 0 Success ;
  837. ; CX != 0 Success ;
  838. ; ;
  839. ; Error Returns: ;
  840. ; AX == 0 ProcInstance not found. ;
  841. ; CX == 0 ProcInstance not found. ;
  842. ; ;
  843. ; Registers Preserved: ;
  844. ; DX,DI,SI,DS ;
  845. ; ;
  846. ; Registers Destroyed: ;
  847. ; BX ;
  848. ; ;
  849. ; Calls: ;
  850. ; nothing ;
  851. ; ;
  852. ; History: ;
  853. ; ;
  854. ; Sat Sep 26, 1987 12:25:42p -by- David N. Weise [davidw] ;
  855. ; ReWrote it a while ago to work with EMS. ;
  856. ;-----------------------------------------------------------------------;
  857. assumes ds,nothing
  858. assumes es,nothing
  859. cProc IFreeProcInstance,<PUBLIC,FAR>,<di>
  860. parmD pproc
  861. cBegin
  862. cCall MISCMapDStoDATA
  863. ReSetKernelDS
  864. mov ax,curTDB
  865. mov es,ax
  866. mov ax,es:[TDB_MPI_Sel]
  867. mov bx,TDB_MPI_Thunks ; Point to start of first table.
  868. fp0: or ax,ax ; Loop through linked tables.
  869. jz fpdone
  870. mov es,ax ; Point to table.
  871. cmp ax,pproc.sel ; This the right ProcInstance table?
  872. jz fp1
  873. mov ax,es:[bx] ; No, get next table.
  874. xor bx,bx
  875. jmp fp0
  876. fp1:
  877. push bx
  878. mov ax, kr1dsc
  879. or al, SEG_RING
  880. cCall IPrestoChangoSelector,<es,ax>
  881. mov es,ax
  882. pop bx
  883. mov di,pproc.off ; Pick off the specific Proc.
  884. xor ax,ax
  885. cld
  886. stosw ; Clear it out!
  887. stosw
  888. stosw
  889. mov ax,di
  890. xchg es:[bx].THUNKSIZE-2,ax ; Update free list.
  891. stosw
  892. mov ax,-1 ; Return success.
  893. cCall HandleAbortProc, <pproc>
  894. fpdone:
  895. mov cx,ax
  896. UnSetKernelDS
  897. cEnd
  898. assumes ds, nothing
  899. assumes es, nothing
  900. cProc DefineHandleTable,<PUBLIC,FAR>,<di>
  901. parmW tblOffset
  902. cBegin
  903. cCall FarMyLock,<ds>
  904. or ax,ax
  905. jz dhtx
  906. mov di,tblOffset
  907. call MISCMapDStoDATA
  908. ReSetKernelDS
  909. push ds
  910. mov ds,curTDB
  911. UnSetKernelDS
  912. or di,di ; resetting PHT?
  913. jnz @F
  914. mov dx,di
  915. @@: mov word ptr ds:[TDB_PHT][2],dx
  916. mov word ptr ds:[TDB_PHT][0],di
  917. pop ds
  918. ReSetKernelDS
  919. or di,di ; Is the app removing the PHT?
  920. jnz @F ; setting new
  921. dec PHTcount ; resetting
  922. jmps dhtx
  923. @@: inc PHTcount ; bump the count of tasks with PHT's
  924. assumes ds, nothing
  925. mov es,ax
  926. mov cx,es:[di] ; Get word count
  927. add di,2 ; Point to first word
  928. xor ax,ax
  929. inc cx ; new handle table format (skip cwClear)
  930. cld
  931. rep stosw ; Zero words in private handle table
  932. inc ax
  933. dhtx:
  934. cEnd
  935. sEnd MISCCODE
  936. end