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.

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