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

1322 lines
24 KiB

  1. TITLE LDUTIL - Loader support procedures
  2. .xlist
  3. include kernel.inc
  4. include newexe.inc
  5. include tdb.inc
  6. include protect.inc
  7. .list
  8. ;externFP GetCurrentPDB
  9. if ROM and PMODE32
  10. externFP HocusROMBase
  11. endif
  12. DataBegin
  13. ;externB Kernel_Flags
  14. ;externW AltfEEMS
  15. externW headTDB
  16. externW hExeHead
  17. ;externW pGlobalHeap
  18. ;externW MyCSDS
  19. externW topPDB
  20. externW cur_dos_pdb
  21. externW Win_PDB
  22. externW curTDB
  23. ;externW segSwapArea
  24. DataEnd
  25. externFP CallWEP
  26. sBegin CODE
  27. assumes CS,CODE
  28. assumes DS,NOTHING
  29. assumes ES,NOTHING
  30. externNP MyUpper
  31. externNP MyLock
  32. externNP LoadNRTable
  33. externNP LoadSegment
  34. externNP GetOwner
  35. externNP GetCachedFileHandle
  36. if SDEBUG
  37. externNP DebugFreeSegment
  38. endif
  39. externFP IGlobalAlloc
  40. externFP IGlobalFree
  41. ;externFP IGlobalLock
  42. externFP IGlobalUnfix
  43. externFP IGlobalHandle
  44. externFP GlobalFlags
  45. externFP FreeNRTable
  46. externFP Int21Handler
  47. ifdef FE_SB ;declare it.
  48. externNP MyIsDBCSLeadByte ;Use near one as we are in the same seg
  49. endif
  50. if ROM
  51. externFP FreeSelector
  52. externNP alloc_data_sel16
  53. endif
  54. cProc SafeCall,<PUBLIC,FAR>
  55. parmD Addr
  56. cBegin
  57. call Addr
  58. cEnd
  59. ;-----------------------------------------------------------------------;
  60. ; GetExePtr ;
  61. ; ;
  62. ; Returns the exe header pointer for the passed handle. ;
  63. ; ;
  64. ; Arguments: ;
  65. ; parmW hinstance ;
  66. ; ;
  67. ; Returns: ;
  68. ; ;
  69. ; Error Returns: ;
  70. ; AX = 0 ;
  71. ; ;
  72. ; Registers Preserved: ;
  73. ; ;
  74. ; Registers Destroyed: ;
  75. ; ;
  76. ; Calls: ;
  77. ; ;
  78. ; History: ;
  79. ; ;
  80. ; Mon Aug 03, 1987 04:40:45p -by- David N. Weise [davidw] ;
  81. ; Rewrote it to work with expanded memory. Note that if the handle ;
  82. ; passed is truly bogus we could still catch a page fault under ;
  83. ; Win386. ;
  84. ;-----------------------------------------------------------------------;
  85. assumes ds, nothing
  86. assumes es, nothing
  87. cProc GetExePtr,<PUBLIC,FAR>
  88. parmW hinstance
  89. cBegin
  90. mov ax,hinstance
  91. test ax,GA_FIXED ; Passed a segment address?
  92. jz not_module
  93. mov es,ax
  94. cmp es:[ne_magic],NEMAGIC ; Yes, does it point to a Module?
  95. jz gxdone
  96. not_module:
  97. SetKernelDS es
  98. mov cx,headTDB
  99. assumes es, nothing
  100. find_TDB:
  101. jcxz last_chance
  102. mov es,cx
  103. cmp ax,es:[TDB_module]
  104. jz found_it
  105. mov cx,es:[TDB_next]
  106. jmp find_TDB
  107. found_it:
  108. mov ax,es:[TDB_pModule]
  109. jmps gxdone
  110. last_chance: ; The problem here is that USER
  111. cCall MyLock,<ax> ; KNOWS that hinstance is but
  112. or ax,ax ; the handle to his data segment.
  113. jz gxdone
  114. mov es,ax
  115. cmp es:[ne_magic],NEMAGIC
  116. je gxdone
  117. cCall GetOwner,<ax>
  118. or ax,ax
  119. jz gxfail
  120. mov es,ax
  121. cmp es:[ne_magic],NEMAGIC
  122. je gxdone
  123. ; The owner,ax, is now a PDB. We gotta find the TDB
  124. SetKernelDS es
  125. mov cx,headTDB
  126. assumes es, nothing
  127. find_PDB:
  128. jcxz gxfail
  129. mov es,cx
  130. cmp ax,es:[TDB_PDB]
  131. jz found_PDB
  132. mov cx,es:[TDB_next]
  133. jmp find_PDB
  134. found_PDB:
  135. mov ax,es:[TDB_pModule]
  136. jmps gxdone
  137. gxfail:
  138. if KDEBUG
  139. xor cx,cx
  140. kerror ERR_LDMODULE,<Invalid module handle>,cx,hinstance
  141. endif
  142. xor ax,ax
  143. gxdone: mov cx,ax
  144. cEnd
  145. ;-----------------------------------------------------------------------;
  146. ; ;
  147. ; GetExpWinVer - return the expected Windows version for a given ;
  148. ; module handle ;
  149. ; ;
  150. ; Arguments: ;
  151. ; parmW hinstance ;
  152. ; ;
  153. ; Returns: ;
  154. ; AX = expected windows version ;
  155. ; DX = BOOL proportional font flag ;
  156. ; ;
  157. ; Error Returns: ;
  158. ; AX = 0 ;
  159. ; ;
  160. ; Registers Preserved: ;
  161. ; ;
  162. ; Registers Destroyed: ;
  163. ; ;
  164. ; Calls: ;
  165. ; ;
  166. ; History: ;
  167. ; ;
  168. ; Fri 06 Jan 1989 -- Written by Sankar. ;
  169. ; ;
  170. ;-----------------------------------------------------------------------;
  171. assumes ds, nothing
  172. assumes es, nothing
  173. cProc GetExpWinVer,<PUBLIC,FAR>, <si,di>
  174. parmW hInstance
  175. cBegin
  176. cCall GetExePtr,<hInstance>
  177. or ax,ax
  178. jz err_GetExpWinVer
  179. mov es,ax
  180. mov ax,es:[ne_expver]
  181. mov dx,es:[ne_flags]
  182. and dx,NEWINPROT
  183. ; error if offsets don't match our defines - In which case find the right
  184. ; offsets and changes the defines in mvdm\inc\tdb16.h
  185. .erre (NE_LOWINVER_OFFSET EQ ne_expver)
  186. .erre (NE_HIWINVER_OFFSET EQ ne_flags)
  187. err_GetExpWinVer:
  188. cEnd
  189. ;-----------------------------------------------------------------------;
  190. ; MyAlloc ;
  191. ; ;
  192. ; Private interface to memory manager ;
  193. ; ;
  194. ; Arguments: ;
  195. ; parmW aflags ;
  196. ; parmW nsize ;
  197. ; parmW nelem ;
  198. ; ;
  199. ; Returns: ;
  200. ; ;
  201. ; Error Returns: ;
  202. ; AX = Handle ;
  203. ; DX = Seg Address ;
  204. ; ;
  205. ; Registers Preserved: ;
  206. ; DI,SI,DS ;
  207. ; ;
  208. ; Registers Destroyed: ;
  209. ; BX,CX,ES ;
  210. ; ;
  211. ; Calls: ;
  212. ; GlobalAlloc ;
  213. ; MyLock ;
  214. ; ;
  215. ; History: ;
  216. ; ;
  217. ; Wed Apr 08, 1987 06:22:57a -by- David N. Weise [davidw] ;
  218. ; Wrote it. ;
  219. ;-----------------------------------------------------------------------;
  220. assumes ds, nothing
  221. assumes es, nothing
  222. cProc MyAllocLinear,<PUBLIC,NEAR>
  223. ; Same as MyAlloc, except for size parameter
  224. parmW aflags
  225. parmD dwBytes
  226. cBegin
  227. jmps MyAllocNBD
  228. cEnd
  229. assumes ds, nothing
  230. assumes es, nothing
  231. cProc MyAlloc,<PUBLIC,NEAR>
  232. parmW aflags
  233. parmD dwBytes
  234. ; parmW nsize
  235. ; parmW nelem
  236. cBegin
  237. xor dx,dx
  238. mov ax,seg_dwBytes ;nsize
  239. mov cx,off_dwBytes ;nelem
  240. jcxz ma3
  241. ma2:
  242. shl ax,1
  243. rcl dx,1
  244. loop ma2
  245. ma3:
  246. mov seg_dwBytes, dx
  247. mov off_dwBytes, ax
  248. MyAllocNBD:
  249. SetKernelDS es
  250. mov cx,aflags
  251. mov al,NSTYPE
  252. and al,cl ; al has SEGTYPE
  253. mov bx,NSDISCARD
  254. and bx,cx
  255. jz @F
  256. shr bx,1
  257. shr bx,1
  258. shr bx,1
  259. shr bx,1 ; BX has GA_DISCARDABLE
  260. cmp al,NSCODE
  261. jne @F
  262. or bl,GA_DISCCODE ; Allocating discardable code
  263. @@:
  264. cmp al,NSDATA
  265. jne @F
  266. and cx,NOT NSWINCODE ; undo Excel bogusness
  267. or bl,GA_DGROUP ; Allocating automatic data segment
  268. @@:
  269. test cl,NSMOVE
  270. jz @F
  271. or bl,GA_MOVEABLE
  272. @@:
  273. cmp al,NSTYPE
  274. jz @F
  275. or bh,GA_CODE_DATA
  276. @@:
  277. cCall IGlobalAlloc,<bx,dwBytes> ;dxax>
  278. assumes es, nothing
  279. push ax
  280. test al,GA_FIXED
  281. jnz @F
  282. cCall MyLock,<ax>
  283. @@:
  284. pop dx
  285. cEnd
  286. ;
  287. ; MyLock( hseg ) - Procedure to return the physical segment address of
  288. ; the passed handle.
  289. ;
  290. ;;;cProc MyLock,<PUBLIC,NEAR>
  291. ;;; parmW hseg
  292. ;;;cBegin
  293. ;;; cCall IGlobalHandle,<hseg>
  294. ;;; xchg dx,ax
  295. ;;;cEnd
  296. ;-----------------------------------------------------------------------;
  297. ; MyFree ;
  298. ; ;
  299. ; Frees a segment allocated by MyAlloc. ;
  300. ; ;
  301. ; Arguments: ;
  302. ; ;
  303. ; Returns: ;
  304. ; ;
  305. ; Error Returns: ;
  306. ; ;
  307. ; Registers Preserved: ;
  308. ; ;
  309. ; Registers Destroyed: ;
  310. ; ;
  311. ; Calls: ;
  312. ; ;
  313. ; History: ;
  314. ; ;
  315. ; Tue Dec 09, 1986 12:48:43p -by- David N. Weise [davidw] ;
  316. ; Added this nifty comment block. ;
  317. ;-----------------------------------------------------------------------;
  318. assumes ds, nothing
  319. assumes es, nothing
  320. cProc MyFree,<PUBLIC,NEAR>
  321. parmW hseg
  322. localW pseg
  323. cBegin
  324. mov bx,hseg
  325. or bx,bx
  326. jz mf3
  327. mov ax,bx
  328. xor cx,cx
  329. test bl,GA_FIXED
  330. jnz mf0a
  331. push bx
  332. cCall GlobalFlags,<bx>
  333. mov cx, ax
  334. xor ax, ax
  335. pop bx
  336. xchg ch, cl
  337. test cl, HE_DISCARDED
  338. jnz mf0a
  339. mov ax, bx
  340. HtoS ax
  341. mf0a:
  342. if KDEBUG
  343. push cx
  344. endif
  345. mov pseg,ax
  346. or ax,ax
  347. jz mf1
  348. mf0:
  349. if SDEBUG
  350. cCall DebugFreeSegment,<pseg,0>
  351. endif
  352. mf1:
  353. if KDEBUG
  354. pop cx
  355. or ch,ch
  356. jz mf2
  357. mf1a:
  358. push cx
  359. cCall IGlobalUnfix,<hseg> ; Prevent RIP if freeing locked DS
  360. pop cx
  361. dec ch
  362. or ch,ch ; If still lock, do it again
  363. jnz mf1a
  364. endif
  365. mf2:
  366. cCall IGlobalFree,<hseg>
  367. mf3:
  368. cEnd
  369. ;-----------------------------------------------------------------------;
  370. ; EntProcAddress
  371. ;
  372. ; Returns the fixed address of a procedure.
  373. ;
  374. ; Entry:
  375. ;
  376. ; Returns:
  377. ; DX:AX = thunk for moveable
  378. ; DX:AX = procedure for fixed
  379. ; AX = constant, ES:BX => constant for absolutes
  380. ; Registers Destroyed:
  381. ;
  382. ; History:
  383. ; Wed 30-Nov-1988 19:39:05 -by- David N. Weise [davidw]
  384. ;
  385. ;-----------------------------------------------------------------------;
  386. assumes ds, nothing
  387. assumes es, nothing
  388. cProc EntProcAddress,<PUBLIC,NEAR>,<si,di>
  389. parmW hExe
  390. parmW entno
  391. if KDEBUG
  392. parmW bNoRip ; if 1 don't RIP for error, 0 -> do the RIP
  393. endif
  394. cBegin
  395. mov es,hExe
  396. mov cx,entno
  397. and cx,7fffh ; clear ResidentName bit (#5108 donc)
  398. jcxz entfail
  399. dec cx
  400. mov si,es:[ne_enttab]
  401. entloop:
  402. mov ax, es:[si.PM_entstart]
  403. cmp cx, ax ; Below this block?
  404. jb entfail ; yes, must be invalid!
  405. cmp cx, es:[si.PM_entend] ; Above this block?
  406. jae entnext ; yes, go to next block
  407. sub cx, ax ; Found the right block, get offset
  408. mov bx, cx
  409. shl cx, 1
  410. add bx, cx
  411. add bx, cx ; bx = cx*5
  412. lea si, [si+bx+size PM_entstruc]
  413. mov bx, si
  414. jmps gotent
  415. entnext:
  416. mov si, es:[si.PM_entnext] ; Next block
  417. or si, si
  418. jnz entloop
  419. jmps entfail
  420. entfail:
  421. if KDEBUG
  422. cmp bNoRip,0
  423. jnz dont_rip_here
  424. mov bx,entno
  425. krDebugOut <DEB_WARN or DEB_krLoadSeg>, "Invalid ordinal reference (##BX) to %ES1"
  426. ; kerror ERR_LDORD,<Invalid ordinal reference to >,es,bx
  427. dont_rip_here:
  428. endif
  429. xor dx,dx
  430. xor ax,ax
  431. jmps entdone
  432. ; Here if the current block has the entry we want
  433. gotabs:
  434. add bx,pentoffset ; make ES:BX point to constant (SLIME!)
  435. mov dx,-1 ; make != 0 since abs might be!
  436. jmps gotent1 ; Offset is symbol value
  437. gotent:
  438. xor ax, ax
  439. mov al, es:[bx].penttype ; Get segno/type field
  440. mov si,es:[bx].pentoffset
  441. cmp al,ENT_ABSSEG ; If segno field absoulute segment
  442. je gotabs ; Yes, have absolute symbol
  443. cmp al, ENT_MOVEABLE
  444. je gotmoveable
  445. .errnz 10 - SIZE NEW_SEG1
  446. ; ax = segno
  447. push bx
  448. mov bx, es:[ne_segtab] ; see if really fixed
  449. mov cx, ax ; look up in seg table
  450. dec cx
  451. shl cx, 1 ; get segtable + (segno-1)*10
  452. add bx, cx
  453. shl cx, 2
  454. add bx, cx
  455. test es:[bx].ns_flags, NSMOVE + NSALLOCED
  456. pop bx
  457. jnz gotmoveable
  458. mov cx,-1 ; Fixed, make sure it's loaded
  459. cCall LoadSegment,<es,ax,cx,cx>
  460. or ax,ax
  461. mov dx,ax
  462. jnz gotent1
  463. jmp entfail
  464. gotmoveable:
  465. xor ax,ax
  466. mov al,es:[bx].pentsegno ; Segment number
  467. dec ax
  468. shl ax,1
  469. mov di,ax
  470. shl ax,2
  471. add di,ax
  472. .errnz 10 - SIZE NEW_SEG1
  473. add di,es:[ne_segtab]
  474. mov dx,es:[di].ns_handle
  475. or dx, dx
  476. jnz ok
  477. mov ax, dx ; No handle, probably from an aborted
  478. jmps entdone ; LoadModule - just return 0:0
  479. ok:
  480. Handle_To_Sel dl
  481. gotent1:
  482. mov ax,si
  483. entdone:
  484. mov cx,ax
  485. or cx,dx
  486. cEnd
  487. ;-----------------------------------------------------------------------;
  488. ; FindOrdinal ;
  489. ; ;
  490. ; Searches the resident and non-resident name tables for a procedure ;
  491. ; name and return its corresponding entry ordinal. ;
  492. ; ;
  493. ; Arguments: ;
  494. ; parmW hExe ;
  495. ; parmD lpname pointer name, strings starts with length ;
  496. ; parmW fh file handle NOT to be discarded from cache ;
  497. ; ;
  498. ; Returns: ;
  499. ; AX = ordinal number ;
  500. ; ;
  501. ; Error Returns: ;
  502. ; ;
  503. ; Registers Preserved: ;
  504. ; ;
  505. ; Registers Destroyed: ;
  506. ; ;
  507. ; Calls: ;
  508. ; MyUpper ;
  509. ; LoadNRTable ;
  510. ; FreeNRTable ;
  511. ; ;
  512. ; History: ;
  513. ; ;
  514. ; Tue 09-May-1989 18:38:04 -by- David N. Weise [davidw] ;
  515. ; Added the batching if out of memory. ;
  516. ; ;
  517. ; Thu Sep 17, 1987 08:55:05p -by- David N. Weise [davidw] ;
  518. ; Added this nifty comment block and fixed it. ;
  519. ;-----------------------------------------------------------------------;
  520. assumes ds, nothing
  521. assumes es, nothing
  522. CLNRBUFFER equ 150
  523. cProc FindOrdinal,<PUBLIC,NEAR>,<si,di>
  524. parmW hExe
  525. parmD lpname
  526. parmW fh
  527. if ROM
  528. localW fInROM
  529. endif
  530. localD oNRTable ; if batching, continue here
  531. localV LoadNRbuffer,CLNRBUFFER ; if batching this is temp buffer
  532. cBegin
  533. xor ax,ax
  534. mov oNRTable.hi,ax
  535. mov oNRTable.lo,ax
  536. if ROM
  537. mov fInROM,ax ; assume module not in ROM
  538. endif
  539. les si,lpname
  540. cmp byte ptr es:[si+1],'#'
  541. je foint
  542. fonorm: push ds
  543. mov ds,hExe
  544. if ROM
  545. test ds:[ne_flags],NEMODINROM ; is module actually in ROM?
  546. jz @f
  547. inc fInROM
  548. @@:
  549. endif
  550. mov si,ds:[ne_restab]
  551. cld
  552. foinit: xor ax,ax ; Skip module name or description
  553. lodsb
  554. add si,ax
  555. inc si
  556. inc si
  557. foloop: lodsb ; get length of entry
  558. les di,lpname
  559. mov cx,ax
  560. jcxz fodone ; no more entries?
  561. cmp es:[di],al ; do lengths match?
  562. jne noteq
  563. inc di
  564. fo_find:
  565. mov al,es:[di]
  566. call MyUpper
  567. mov bl,ds:[si]
  568. inc si
  569. inc di
  570. cmp al,bl
  571. jne noteq1
  572. loop fo_find
  573. ; repe cmpsb
  574. ; jne noteq
  575. lodsw ; get ordinal number!
  576. mov bx,ds
  577. pop ds
  578. cmp hExe,bx ; did we load the nrtable?
  579. jnz foexit_j
  580. jmp foexit1
  581. foexit_j:
  582. jmp foexit
  583. noteq1: dec cx
  584. noteq: add si,cx
  585. inc si
  586. inc si
  587. jmps foloop
  588. ; Here if pName points to string of the form: #nnnn
  589. foint: lods byte ptr es:[si] ; nbytes = *pName++
  590. mov cl,al
  591. xor ch,ch
  592. dec cx ; ignore #
  593. inc si
  594. xor ax,ax ; sum = 0
  595. foint0: mov dx,ax
  596. lods byte ptr es:[si] ; c = *pName++
  597. sub al,'0' ; if (!isdigit(c))
  598. cmp al,9
  599. ja fonorm ; treat like normal
  600. xor ah,ah
  601. mov bx,ax ; sum = (sum * 10) + (c - '0')
  602. mov al,10
  603. mul dx
  604. add ax,bx
  605. loop foint0
  606. jmp foexit1
  607. fodone: mov bx,ds
  608. pop ds
  609. ;%out help me ; what was this line for?
  610. mov cx,oNRTable.hi
  611. cmp cx,oNRTable.lo
  612. jnz fo_batching
  613. cmp hExe,bx ; have we looked at NRTable yet?
  614. if ROM
  615. jne foexit_j
  616. else
  617. jne foexit
  618. endif
  619. if ROM
  620. cmp fInROM,0 ; this module in ROM?
  621. jz fo_nr_not_in_rom
  622. cCall FindROMNRTable,<hExe> ; yes, get selector to ROM NR Table
  623. mov fInROM,ax
  624. push ds
  625. mov ds,ax ; ds -> ROM NR table
  626. xor bx,bx
  627. mov bl,ds:[0] ; skip over first NR table entry
  628. lea si,[bx+3] ; (the module description string)
  629. xor ax,ax
  630. jmp foloop
  631. fo_nr_not_in_ROM:
  632. endif
  633. fo_batching:
  634. xor bx,bx
  635. mov ax,fh
  636. ;;; cmp ax,-1
  637. ;;; jz no_file_handle
  638. SetKernelDS ES
  639. ;;; mov dx, topPDB
  640. ;;; mov es, curTDB
  641. ;;; UnSetKernelDS es
  642. ;;; mov ax, es:[TDB_PDB]
  643. ;;;
  644. ;;; cmp dx, cur_dos_pdb
  645. ;;; jz @F
  646. ;;; mov bx,ax
  647. ;;;@@:
  648. mov bx, Win_PDB
  649. UnSetKernelDS
  650. mov dx, -1
  651. cCall GetCachedFileHandle,<hexe,ax,dx>
  652. no_file_handle:
  653. push bx
  654. lea cx,LoadNRbuffer
  655. mov dx,CLNRBUFFER
  656. cCall LoadNRTable,<hexe,ax,oNRTable,ss,cx,dx>
  657. if KDEBUG
  658. push es
  659. push di
  660. les di, [lpName]
  661. krDebugOut <DEB_TRACE or DEB_krLoadSeg>, " looking for @ES:DI"
  662. pop di
  663. pop es
  664. endif
  665. pop si
  666. or si,si
  667. jz @F
  668. ;;; push ax
  669. ;;; push bx
  670. ;;; mov bx,si
  671. ;;; mov ah,50h
  672. ;;; DOSCALL
  673. ;;; pop bx
  674. ;;; pop ax
  675. push es
  676. SetKernelDS ES
  677. mov Win_PDB, si
  678. pop es
  679. UnSetKernelDS ES
  680. @@: mov oNRTable.hi,cx
  681. mov oNRTable.lo,bx
  682. push ds
  683. mov ds,dx
  684. mov si,ax
  685. or ax,dx ; did we get a table?
  686. jz @F
  687. xor ax,ax
  688. jmp foloop
  689. @@: pop ds
  690. foexit: push ax
  691. if ROM
  692. cmp fInROM,0 ; this module in ROM
  693. jz @f
  694. cCall FreeSelector,<fInROM> ; yes, free ROM NR table selector
  695. jmps foexit0
  696. @@:
  697. endif
  698. mov ax,ne_nrestab
  699. cCall FreeNRTable,<hExe,ax>
  700. foexit0:
  701. pop ax
  702. foexit1:
  703. ;??? commented out 3/7/88 by rong
  704. ;??? we should put this back in once everyone has the new keyboard driver
  705. ;if KDEBUG
  706. ; or ax,ax
  707. ; jnz foexit2
  708. ; les bx,lpname
  709. ; inc bx
  710. ; kerror ERR_LDNAME,<Invalid procedure name >,es,bx
  711. ; xor ax,ax
  712. ;foexit2:
  713. ;endif
  714. cEnd
  715. if ROM ;----------------------------------------------------------------
  716. ;-----------------------------------------------------------------------
  717. ; FindROMNRTable
  718. ;
  719. ; Returns a selector to the ROM copy of the Non-Resident name table for
  720. ; a module stored in ROM.
  721. ;
  722. ; Arguments:
  723. ; parmW hExe
  724. ;
  725. ; Returns:
  726. ; AX = selector mapping NR table
  727. ;
  728. ;-----------------------------------------------------------------------
  729. assumes ds, nothing
  730. assumes es, nothing
  731. cProc FindROMNRTable,<PUBLIC,NEAR>,<ds>
  732. parmW hExe
  733. cBegin
  734. mov ds,hExe
  735. mov ax,word ptr ds:[ne_nrestab]
  736. mov bx,word ptr ds:[ne_nrestab+2]
  737. cCall alloc_data_sel16,<bx,ax,1000h>
  738. if PMODE32
  739. cCall HocusROMBase, <ax>
  740. endif
  741. if KDEBUG
  742. or ax,ax
  743. jnz @f
  744. int 3
  745. @@:
  746. endif
  747. cEnd
  748. endif ;ROM ---------------------------------------------------------
  749. ; Search the list of new EXE headers for the passed executable file name
  750. ; (no path)
  751. ;
  752. ; this must be resident so we can search for modules in the file handle
  753. ; cache from the int 21 handler -- craigc
  754. ;
  755. cProc ResidentFindExeFile,<PUBLIC,FAR>,<ds,si,di>
  756. parmD pname
  757. cBegin
  758. SetKernelDS
  759. mov ax,hExeHead
  760. ffloop:
  761. or ax,ax
  762. jz ffdone
  763. mov es,ax
  764. mov di,es:[ne_pfileinfo]
  765. or di,di
  766. jz ffnext
  767. ;
  768. ; Double Byte Character is not able to search from the end of string,
  769. ; so this function must search from the top of string.
  770. ;
  771. ifdef FE_SB
  772. lea si,[di.opFile] ; get address of file name
  773. mov cl,es:[di.opLen] ; get structure length
  774. xor ch,ch
  775. add cx,di
  776. mov di,cx ; save end address
  777. sub cx,si ; get length of file name
  778. mov bx,si ; save top address of file name
  779. cld
  780. delineator_loop:
  781. lods byte ptr es:[si]
  782. call MyIsDBCSLeadByte
  783. jc delineator_notlead ; if not DBCS lead byte
  784. dec cx
  785. jcxz delineator_next
  786. inc si
  787. loop delineator_loop
  788. jmp delineator_next
  789. delineator_notlead:
  790. cmp al,"\"
  791. jz found_delineator
  792. cmp al,":"
  793. jz found_delineator
  794. loop delineator_loop
  795. jmp delineator_next
  796. found_delineator:
  797. mov bx,si ; save delineator address
  798. loop delineator_loop
  799. delineator_next:
  800. xchg bx,di ; set address of file name to di
  801. sub bx,di ; get lenfth of file name
  802. else
  803. mov si,di
  804. xor cx,cx
  805. mov cl,es:[di]
  806. add si,cx
  807. dec si
  808. std
  809. xor bx,bx
  810. delineator_loop: ; look for beginning of name
  811. lods byte ptr es:[si]
  812. cmp al,"\"
  813. jz found_delineator
  814. cmp al,":"
  815. jz found_delineator
  816. inc bx
  817. loop delineator_loop
  818. dec si
  819. found_delineator: ; ES:SI -> before name
  820. mov di,si
  821. inc di
  822. inc di
  823. endif
  824. lds si,pname
  825. UnSetKernelDS
  826. mov cx,bx
  827. cld
  828. repe cmpsb
  829. mov ax,es
  830. je ffdone
  831. ffnext:
  832. mov ax,word ptr es:[ne_pnextexe]
  833. jmp ffloop
  834. ffdone:
  835. cEnd
  836. sEnd CODE
  837. externFP FarLoadSegment
  838. sBegin NRESCODE
  839. assumes CS,NRESCODE
  840. assumes DS,NOTHING
  841. assumes ES,NOTHING
  842. externNP DelModule
  843. externNP MapDStoDATA
  844. cProc FindExeFile,<PUBLIC,NEAR>
  845. parmD pFile
  846. cBegin
  847. cCall ResidentFindExeFile, <pFile>
  848. cEnd
  849. ; Search the list of new EXE headers for the passed executable name
  850. cProc FindExeInfo,<PUBLIC,NEAR>,<ds,si,di>
  851. parmD pname
  852. parmW nchars
  853. cBegin
  854. cCall MapDStoDATA
  855. ReSetKernelDS
  856. mov bx,nchars
  857. mov ax,hExeHead
  858. feloop:
  859. or ax,ax
  860. jz fedone
  861. mov es,ax
  862. mov di,es:[ne_restab]
  863. cmp es:[di],bl
  864. jne fenext
  865. inc di
  866. lds si,pname
  867. UnSetKernelDS
  868. mov cx,bx
  869. repe cmpsb
  870. je fedone
  871. fenext:
  872. mov ax,word ptr es:[ne_pnextexe]
  873. jmp feloop
  874. fedone:
  875. cEnd
  876. cProc FarFindExeInfo,<PUBLIC,FAR>
  877. parmD pname
  878. parmW nchars
  879. cBegin
  880. cCall FindExeInfo,<pname,nchars>
  881. cEnd
  882. ;
  883. ; IncExeUsage( hExe ) - procedure to increment the usage count of this
  884. ; EXE header. Indirectly increments the usage count of all the EXE
  885. ; headers it points to.
  886. ;
  887. cProc IncExeUsage,<PUBLIC,NEAR>,<ax,di>
  888. parmW hexe
  889. cBegin
  890. mov cx,hexe
  891. jcxz iexj
  892. mov es,cx
  893. cmp es:[ne_magic],NEMAGIC
  894. jne iexj
  895. test es:[ne_usage],8000h
  896. jz iego
  897. iexj:
  898. krDebugOut <DEB_ERROR or DEB_KRLOADMOD>, "IncExeUsage(#ES) not DLL"
  899. jmp iex
  900. iego:
  901. cmp es:[ne_usage], 4000h
  902. jb OKusage
  903. krDebugOut DEB_FERROR, "IncExeUsage: ne_usage overflow"
  904. OKusage:
  905. ;
  906. ; Save time and space by saving stuff on stack
  907. ; rather than recursing.
  908. ;
  909. or es:[ne_usage], 8000h
  910. NextExe0:
  911. or es:[ne_usage], 4000h ; Mark node visited
  912. inc es:[ne_usage]
  913. ;if kdebug
  914. ; push ax
  915. ; mov ax, es:[ne_usage]
  916. ; krDebugOut <DEB_TRACE or DEB_krLoadMod>, "IncExeUsage(%ES0) #ax"
  917. ; pop ax
  918. ;endif
  919. mov cx,es:[ne_cmod]
  920. jcxz NoDeps0
  921. mov di,es:[ne_modtab]
  922. ieloop:
  923. push es
  924. cmp word ptr es:[di], 0
  925. je ieloop1
  926. lar ax, es:[di] ; Make sure valid selector
  927. jnz ieloop1
  928. mov es, es:[di]
  929. cmp es:[ne_magic],NEMAGIC
  930. jne ieloop1
  931. test es:[ne_usage], 0C000h
  932. jnz ieloop1
  933. push cx
  934. push di ; Fake recursion
  935. jmp NextExe0
  936. NextExeDone0: ; Return from fake recursion
  937. pop di
  938. pop cx
  939. ieloop1:
  940. pop es
  941. add di,2
  942. loop ieloop
  943. NoDeps0:
  944. mov cx, es
  945. cmp cx, hExe
  946. jne NextExeDone0
  947. NextExe1:
  948. and es:[ne_usage], NOT 4000h ; Mark node visited
  949. mov cx,es:[ne_cmod]
  950. jcxz NoDeps1
  951. mov di,es:[ne_modtab]
  952. UnMarkLoop:
  953. push es
  954. cmp word ptr es:[di], 0
  955. je UnMarkLoop1
  956. lar ax, es:[di] ; Make sure valid selector
  957. jnz UnMarkLoop1
  958. mov es, es:[di]
  959. cmp es:[ne_magic],NEMAGIC
  960. jne UnMarkLoop1
  961. test es:[ne_usage], 08000h
  962. jnz UnMarkLoop1
  963. test es:[ne_usage], 04000h
  964. jz UnMarkLoop1
  965. push cx
  966. push di ; Fake recursion
  967. jmp NextExe1
  968. NextExeDone1: ; Return from fake recursion
  969. pop di
  970. pop cx
  971. UnMarkLoop1:
  972. pop es
  973. add di,2
  974. loop UnMarkLoop
  975. NoDeps1:
  976. mov cx, es
  977. cmp cx, hExe
  978. jne NextExeDone1
  979. xor es:[ne_usage], 8000h
  980. iex:
  981. cEnd
  982. ;-----------------------------------------------------------------------;
  983. ; DecExeUsage ;
  984. ; ;
  985. ; Decrements the usage count of the given EXE header. Indirectly ;
  986. ; decrements the usage count of all the EXE headers it points to. ;
  987. ; ;
  988. ; Arguments: ;
  989. ; parmW hexe ;
  990. ; ;
  991. ; Returns: ;
  992. ; ZF = 1 if usage count is now zero. ;
  993. ; ;
  994. ; Error Returns: ;
  995. ; ;
  996. ; Registers Preserved: ;
  997. ; DI,SI,DS ;
  998. ; ;
  999. ; Registers Destroyed: ;
  1000. ; AX,BX,CX,DX,ES ;
  1001. ; ;
  1002. ; Calls: ;
  1003. ; DecExeUsage ;
  1004. ; DelModule ;
  1005. ; ;
  1006. ; History: ;
  1007. ; ;
  1008. ; Mon Sep 21, 1987 01:21:00p -by- David N. Weise [davidw] ;
  1009. ; Added this nifty comment block. ;
  1010. ;-----------------------------------------------------------------------;
  1011. cProc DecExeUsage,<PUBLIC,NEAR>,<ds,di,si>
  1012. parmW hexe
  1013. cBegin
  1014. call MapDStoDATA
  1015. ReSetKernelDS
  1016. xor si,si
  1017. mov cx,hexe
  1018. xor ax,ax
  1019. jcxz dexj
  1020. mov es,cx
  1021. cmp es:[si].ne_magic,NEMAGIC
  1022. jne dexj
  1023. test es:[si].ne_usage,8000h
  1024. jz dego
  1025. dexj:
  1026. krDebugOut <DEB_ERROR or DEB_KRLOADMOD>, "DecExeUsage(#ES) not DLL"
  1027. jmp dex
  1028. dego:
  1029. ;
  1030. ; Save time and space by saving stuff on stack
  1031. ; rather than recursing.
  1032. ;
  1033. dec es:[si].ne_usage
  1034. or es:[si].ne_usage, 8000h
  1035. ;if kdebug
  1036. ; push ax
  1037. ; mov ax, es:[si].ne_usage
  1038. ; krDebugOut <DEB_TRACE or DEB_krLoadMod>, "DecExeUsage(%ES0) #ax"
  1039. ; pop ax
  1040. ;endif
  1041. NextExe2:
  1042. or es:[si].ne_usage, 4000h ; Mark node visited
  1043. mov cx,es:[si].ne_cmod
  1044. jcxz NoDeps2
  1045. mov di,es:[si].ne_modtab
  1046. MarkLoop2:
  1047. push es
  1048. cmp si, es:[di]
  1049. je MarkLoop3
  1050. lar ax, es:[di] ; Make sure valid selector
  1051. jnz MarkLoop3
  1052. mov es, es:[di]
  1053. cmp es:[si].ne_magic,NEMAGIC
  1054. jne MarkLoop3
  1055. test es:[si].ne_usage, 0C000h
  1056. jnz MarkLoop3
  1057. push cx
  1058. push di ; Fake recursion
  1059. jmp NextExe2
  1060. NextExeDone2: ; Return from fake recursion
  1061. pop di
  1062. pop cx
  1063. MarkLoop3:
  1064. pop es
  1065. add di,2
  1066. loop MarkLoop2
  1067. NoDeps2:
  1068. mov cx, es
  1069. cmp cx, hExe
  1070. jne NextExeDone2
  1071. xor cx, cx
  1072. push cx ; End of list of Exes to delete
  1073. mov di, hExeHead ; Scan Exes once to dec them
  1074. scan_exes:
  1075. or di, di
  1076. jz de_done
  1077. mov es, di
  1078. mov di, es:[si].ne_pnextexe
  1079. test es:[si].ne_usage, 4000h
  1080. jz scan_exes
  1081. and es:[si].ne_usage, NOT 4000h ; Remove the mark
  1082. test es:[si].ne_usage, 8000h ; Skip this one?
  1083. jnz scan_exes
  1084. ; krDebugOut <DEB_TRACE or DEB_krLoadMod>, "DecExeUsage dependent %ES0"
  1085. dec es:[si].ne_usage
  1086. jnz scan_exes
  1087. push es ; We will delete this one
  1088. jmps scan_exes
  1089. de_done: ; Call WEP each module before
  1090. mov bx, sp ; we free any modules
  1091. de_done0:
  1092. mov cx, ss:[bx]
  1093. add bx, 2
  1094. jcxz de_done1
  1095. push bx
  1096. cCall CallWEP, <cx, 0>
  1097. pop bx
  1098. jmps de_done0
  1099. de_done1:
  1100. pop cx ; Get next module to delete
  1101. jcxz all_deleted
  1102. cCall DelModule,<cx> ; Delete him
  1103. jmps de_done1
  1104. all_deleted:
  1105. mov es, hExe
  1106. and es:[si].ne_usage,NOT 0C000h
  1107. dex:
  1108. cEnd
  1109. ;
  1110. ; StartProcAddress( hExe ) - procedure to return the fixed address of
  1111. ; a new EXE start procedure
  1112. ;
  1113. cProc StartProcAddress,<PUBLIC,NEAR>,<di>
  1114. parmW hexe
  1115. parmW fh
  1116. cBegin
  1117. mov es,hexe
  1118. mov di,ne_csip
  1119. xor dx,dx
  1120. mov ax,es:[di+2]
  1121. or ax,ax
  1122. jz sp1
  1123. mov di,es:[di]
  1124. cCall FarLoadSegment,<es,ax,fh,fh>
  1125. jcxz sp1
  1126. mov ax,di ; DX:AX is start address of module
  1127. sp1: ; (DX is really a handle)
  1128. mov cx,ax
  1129. or cx,dx
  1130. cEnd
  1131. ; GetStackPtr - returns the initial SS:SP for a module.
  1132. ;
  1133. cProc GetStackPtr,<PUBLIC,NEAR>,<si>
  1134. parmW hExe
  1135. cBegin
  1136. mov es,hExe
  1137. if KDEBUG
  1138. cmp es:[ne_sssp].sel,0
  1139. jnz @F
  1140. mov cx,ne_sssp
  1141. fkerror 0,<Invalid stack segment>,es,cx
  1142. @@:
  1143. endif
  1144. cmp es:[ne_sssp].off,0
  1145. jne re3
  1146. mov dx,es:[ne_stack]
  1147. mov bx,es:[ne_pautodata]
  1148. or bx,bx
  1149. jz re2
  1150. add dx,es:[bx].ns_minalloc
  1151. re2: and dx,0FFFEh ; Word aligned stack
  1152. mov word ptr es:[ne_sssp],dx
  1153. re3: mov dx,es:[ne_sssp].sel
  1154. mov ax,es:[ne_sssp].off
  1155. push ax
  1156. mov cx,-1
  1157. cCall FarLoadSegment,<es,dx,cx,cx>
  1158. pop ax ; Handle in DX and offset in AX
  1159. cEnd
  1160. ;
  1161. ; GetInstance( hExe ) - Procedure to return the instance handle for
  1162. ; the current automatic data segment associated with the passed exe
  1163. ;
  1164. cProc GetInstance,<PUBLIC,NEAR>
  1165. parmW hexe
  1166. cBegin
  1167. mov es,hexe
  1168. mov ax,es:[ne_flags]
  1169. test ax,NEINST+NESOLO
  1170. mov ax,es
  1171. jz gidone
  1172. mov bx,es:[ne_pautodata]
  1173. or bx,bx
  1174. jz gidone
  1175. mov ax,es:[bx].ns_handle
  1176. gidone:
  1177. mov cx,ax
  1178. cEnd
  1179. sEnd NRESCODE
  1180. end