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.

3740 lines
80 KiB

  1. .xlist
  2. include kernel.inc
  3. include newexe.inc
  4. include tdb.inc
  5. include pdb.inc
  6. include eems.inc
  7. include protect.inc
  8. .list
  9. NEWEPME = NEPRIVLIB ; flag saying Call WEP on exit
  10. externW pLocalHeap
  11. externW pStackTop
  12. DataBegin
  13. externB num_tasks
  14. externB graphics
  15. externB fBooting
  16. externB Kernel_flags
  17. externB WOAName
  18. externW fLMdepth
  19. externW headPDB
  20. externW curTDB
  21. externW loadTDB
  22. externW Win_PDB
  23. externW topPDB
  24. externW hExeHead
  25. ;externW EMS_calc_swap_line
  26. externW WinFlags
  27. externW hGDI
  28. externW hUser
  29. ifdef WOW
  30. externW OFContinueSearch
  31. endif
  32. externD pMBoxProc
  33. externD pGetFreeSystemResources
  34. externD dressed_for_success
  35. externD lpGPChain
  36. ;** Diagnostic mode stuff
  37. externW fDiagMode
  38. externB szLoadStart
  39. externB szCRLF
  40. externB szLoadSuccess
  41. externB szLoadFail
  42. externB szFailCode
  43. externB szCodeString
  44. if ROM
  45. externW selROMTOC
  46. endif
  47. ; Look for module in Module Compatibilty section of win.ini
  48. szModuleCompatibility DB 'ModuleCompatibility',0
  49. DataEnd
  50. if ROM and PMODE32
  51. externFP HocusROMBase
  52. endif
  53. externFP Yield
  54. externFP CreateTask
  55. externFP GlobalAlloc
  56. externFP GlobalSize
  57. externFP GlobalLock
  58. externFP GlobalUnlock
  59. externFP GlobalFree
  60. externFP LocalAlloc
  61. externFP LocalFree
  62. externFP LocalCountFree
  63. externFP LoadModule
  64. externFP lstrlen
  65. externFP _lclose
  66. externFP FreeModule
  67. externFP GetModuleHandle
  68. externFP LoadExeHeader
  69. externFP GetExePtr
  70. externFP GetProcAddress
  71. externFP MyOpenFile
  72. externFP FarGetCachedFileHandle
  73. externFP FarEntProcAddress
  74. externFP FlushCachedFileHandle
  75. externFP FarMyLock
  76. externFP FarMyFree
  77. externFP FarMyUpper
  78. externFP FarLoadSegment
  79. externFP FarDeleteTask
  80. externFP FarUnlinkObject
  81. externFP Far_genter
  82. externFP AllocSelector
  83. externFP FreeSelector
  84. externFP LongPtrAdd
  85. externFP GetProfileInt
  86. if ROM
  87. externFP ChangeROMHandle
  88. externFP UndefDynLink
  89. externFP GetProcAddress
  90. externFP IPrestoChangoSelector
  91. externFP far_alloc_data_sel16
  92. externFP far_free_temp_sel
  93. endif
  94. ifdef WOW
  95. externFP StartWOWTask
  96. externFP WowIsKnownDLL
  97. externFP LongPtrAddWOW
  98. externFP AllocSelectorWOW
  99. externFP WOWLoadModule
  100. externFP WowShutdownTimer
  101. externB fShutdownTimerStarted
  102. externB fExitOnLastApp
  103. externFP WowSyncTask
  104. endif
  105. ifdef FE_SB
  106. externFP FarMyIsDBCSLeadByte
  107. endif
  108. externFP FreeTDB
  109. ;** Diagnostic mode
  110. externFP DiagOutput
  111. sBegin CODE
  112. assumes CS,CODE
  113. assumes DS,NOTHING
  114. assumes ES,NOTHING
  115. sEnd CODE
  116. sBegin NRESCODE
  117. assumes CS,NRESCODE
  118. assumes DS,NOTHING
  119. assumes ES,NOTHING
  120. externB szProtectCap
  121. externB msgRealModeApp1
  122. externB msgRealModeApp2
  123. externNP MapDStoDATA
  124. externNP FindExeFile
  125. externNP FindExeInfo
  126. externNP AddModule
  127. externNP DelModule
  128. externNP GetInstance
  129. externNP IncExeUsage
  130. externNP DecExeUsage
  131. externNP AllocAllSegs
  132. externNP PreloadResources
  133. externNP StartProcAddress
  134. externNP StartLibrary
  135. externNP GetStackPtr
  136. externNP StartTask
  137. IFNDEF NO_APPLOADER
  138. externNP BootAppl
  139. ENDIF ;!NO_APPLOADER
  140. ;-----------------------------------------------------------------------;
  141. ; OpenApplEnv ;
  142. ; Calls CreateTask ;
  143. ; Allocates temporary stack ;
  144. ; Arguments: ;
  145. ; ;
  146. ; Returns: ;
  147. ; ax = selector of load-time stack ;
  148. ; Error Returns: ;
  149. ; ax = 0 ;
  150. ; Registers Preserved: ;
  151. ; ;
  152. ; Registers Destroyed: ;
  153. ; ;
  154. ; Calls: ;
  155. ; ;
  156. ; History: ;
  157. ; ;
  158. ; Tue 16-Jan-1990 21:13:51 -by- David N. Weise [davidw] ;
  159. ; Ya know, it seems to me that most of the below ain't necessary ;
  160. ; for small frame EMS. But it's too late to change it now. ;
  161. ; ;
  162. ; Fri 07-Apr-1989 23:15:42 -by- David N. Weise [davidw] ;
  163. ; Added support for task ExeHeaders above The Line in Large ;
  164. ; Frame EMS. ;
  165. ; ;
  166. ; Tue Oct 20, 1987 07:48:51p -by- David N. Weise [davidw] ;
  167. ; Added this nifty comment block. ;
  168. ;-----------------------------------------------------------------------;
  169. LOADSTACKSIZE = 2048
  170. assumes ds,nothing
  171. assumes es,nothing
  172. cProc OpenApplEnv,<PUBLIC,NEAR>,<ds,si,di>
  173. parmD lpPBlock
  174. parmW pExe
  175. parmW fWOA
  176. ; localW myCodeDS
  177. ; localW myCurTDB
  178. ; localW myLoadTDB
  179. cBegin
  180. ReSetKernelDS ; Assume DS:KRNLDS
  181. cCall CreateTask,<lpPBlock,pExe,fWOA>
  182. or ax,ax
  183. jz oae_done
  184. test kernel_flags,KF_pUID ; All done booting?
  185. jz oae_done
  186. xor ax,ax
  187. mov bx,LOADSTACKSIZE
  188. mov cx,(GA_ALLOC_LOW or GA_SHAREABLE) shl 8 or GA_ZEROINIT or GA_MOVEABLE
  189. cCall GlobalAlloc,<cx,ax,bx>
  190. or ax,ax
  191. jz oae_done
  192. cCall GlobalLock,<ax>
  193. mov ax,dx
  194. push es ; added 13 feb 1990
  195. mov es,loadTDB
  196. mov es:[TDB_LibInitSeg],ax
  197. mov es:[TDB_LibInitOff],10h
  198. mov es,dx
  199. mov es:[pStackTop],12h
  200. pop es
  201. oae_done:
  202. cEnd
  203. ;-----------------------------------------------------------------------;
  204. ; CloseApplEnv ;
  205. ; ;
  206. ; ;
  207. ; Arguments: ;
  208. ; ;
  209. ; Returns: ;
  210. ; AX = hExe ;
  211. ; BX = ? ;
  212. ; DX = TDB ;
  213. ; ;
  214. ; Error Returns: ;
  215. ; ;
  216. ; Registers Preserved: ;
  217. ; ;
  218. ; Registers Destroyed: ;
  219. ; ..., ES, ... ;
  220. ; ;
  221. ; Calls: ;
  222. ; ;
  223. ; History: ;
  224. ; ;
  225. ; Fri 07-Apr-1989 23:15:42 -by- David N. Weise [davidw] ;
  226. ; Added support for task ExeHeaders above The Line in Large ;
  227. ; Frame EMS. ;
  228. ; ;
  229. ; Tue Oct 20, 1987 07:48:51p -by- David N. Weise [davidw] ;
  230. ; Added this nifty comment block. ;
  231. ;-----------------------------------------------------------------------;
  232. assumes ds,nothing
  233. assumes es,nothing
  234. cProc CloseApplEnv,<PUBLIC,NEAR>,<ds,si,di>
  235. parmW hResult
  236. parmW hExe
  237. localW myCurTDB
  238. localW cae_temp
  239. localW myLoadTDB
  240. cBegin
  241. ReSetKernelDS
  242. ; Copy DS variables to stack, since we may need DS
  243. mov cx,curTDB
  244. mov myCurTDB,cx
  245. mov cx,loadTDB
  246. mov myLoadTDB,cx
  247. mov cae_temp, si
  248. mov ax, myLoadTDB
  249. or ax, ax ; Not set if LMCheckHeap failed
  250. jz cae_done
  251. mov ds, ax
  252. mov ax, ds:[TDB_LibInitSeg]
  253. or ax, ax
  254. jz cae_free_stack1
  255. mov ds, ax
  256. cmp ds:[pStackTop], 12h
  257. jne cae_free_stack1
  258. mov ds,myLoadTDB
  259. push ax
  260. cCall GlobalUnlock,<ax>
  261. call GlobalFree ; parameter pushed above
  262. cae_free_stack1:
  263. mov ds,myLoadTDB
  264. mov ds:[TDB_LibInitSeg],ax
  265. mov ds:[TDB_LibInitOff],10h
  266. ; Copy correct return address
  267. cae_done:
  268. SetKernelDSNRES
  269. xor dx,dx
  270. xchg loadTDB,dx ; Done loading this guy
  271. mov ax,hResult ; if hResult < 32, it's not a real
  272. cmp ax,LME_MAXERR ; handle, and in fact is the invalid
  273. jb cae_cleanup ; format return code. (11).
  274. mov es,dx
  275. ; Start this guy up! TDB_nEvents must be set here, and not before
  276. ; because message boxes may be put up if we can't find libraries,
  277. ; which would have caused this app to prematurely start.
  278. push es
  279. ifdef WOW
  280. cmp num_tasks, 1 ; First task? (except wowexec)
  281. jne @F ; branch if not first task
  282. cmp fExitOnLastApp, 0 ; Shared WOW?
  283. jne @F ; branch if not shared WOW
  284. cmp fShutdownTimerStarted, 1; Is the timer running?
  285. jne @F ; branch if not running
  286. cCall WowShutdownTimer, <0> ; stop shutdown timer
  287. mov fShutdownTimerStarted, 0
  288. @@:
  289. endif
  290. mov es:[TDB_nEvents],1
  291. inc num_tasks ; Do this here or get it wrong.
  292. test es:[TDB_flags],TDBF_OS2APP
  293. jz @F
  294. cmp dressed_for_success.sel,0
  295. jz @F
  296. call dressed_for_success
  297. ifdef WOW
  298. ; Start Up the New Task
  299. @@: cCall StartWOWTask,<es,es:[TDB_taskSS],es:[TDB_taskSP]>
  300. or ax,ax ; Success ?
  301. jnz @f ; Yes
  302. mov hResult,ax ; No - Fake Out of Memory Error 0
  303. ; No error matches failed to create thread
  304. pop dx ; restore TDB
  305. dec num_tasks ;
  306. jmps cae_cleanup ;
  307. endif; WOW
  308. @@: test kernel_flags,KF_pUID ; All done booting?
  309. jz @F ; If booting then don't yield.
  310. cCall WowSyncTask
  311. @@:
  312. assumes ds,nothing
  313. pop dx ; return TDB
  314. jmps cae_exit
  315. ; Failure case - undo the damage
  316. cae_cleanup:
  317. or dx,dx ; Did we even get a TDB?
  318. jz cae_exit ; No.
  319. mov ds,dx
  320. assumes ds,nothing
  321. mov ds:[TDB_sig],ax ; mark TDB as invalid
  322. cCall FarDeleteTask,<ds>
  323. mov es,ds:[TDB_PDB]
  324. mov dx,PDB_Chain
  325. mov bx,dataOffset HeadPDB ; Kernel PDB
  326. cCall FarUnlinkObject
  327. cCall FreeTDB
  328. cae_exit:
  329. xor ax,ax
  330. mov es,ax ; to avoid GP faults in pmode
  331. if PMODE32
  332. .386
  333. mov fs, ax
  334. mov gs, ax
  335. .286
  336. endif
  337. mov ax,hResult
  338. mov bx, cae_temp
  339. cEnd
  340. ;-----------------------------------------------------------------------;
  341. ; StartModule ;
  342. ; ;
  343. ; ;
  344. ; Arguments: ;
  345. ; ;
  346. ; Returns: ;
  347. ; AX = hExe or StartLibrary ;
  348. ; ;
  349. ; Error Returns: ;
  350. ; AX = 0 ;
  351. ; ;
  352. ; Registers Preserved: ;
  353. ; BX,DI,SI,DS ;
  354. ; ;
  355. ; Registers Destroyed: ;
  356. ; ;
  357. ; Calls: ;
  358. ; FarLoadSegment ;
  359. ; StartProcAddress ;
  360. ; StartLibrary ;
  361. ; ;
  362. ; History: ;
  363. ; ;
  364. ; Tue Jan 01, 1980 03:04:49p -by- David N. Weise [davidw] ;
  365. ; ReWrote it from C into assembly and added this nifty comment block. ;
  366. ;-----------------------------------------------------------------------;
  367. assumes ds,nothing
  368. assumes es,nothing
  369. cProc StartModule,<PUBLIC,NEAR>,<di,si>
  370. parmW hPrev
  371. parmD lpPBlock
  372. parmW hExe
  373. parmW fh
  374. localD pf
  375. cBegin
  376. mov ax,hExe
  377. mov es,ax
  378. assumes es,nothing
  379. cmp es:[ne_csip].sel,0
  380. jz start_it_up
  381. ; Make sure DGROUP loaded before we need to load the start segment.
  382. mov cx,es:[ne_autodata]
  383. jcxz start_it_up ; no automatic data segment
  384. cCall FarLoadSegment,<es,cx,fh,fh>
  385. or ax,ax
  386. jnz start_it_up ; auto DS loaded OK
  387. mov ax,fh
  388. inc ax
  389. jz sm_ret1 ; return NULL
  390. dec ax
  391. cCall _lclose,<ax>
  392. xor ax,ax
  393. sm_ret1:
  394. jmps sm_ret ; return NULL
  395. start_it_up:
  396. cCall StartProcAddress,<hExe,fh> ; just because it's preloaded
  397. mov pf.sel,dx ; doesn't mean it's still around!
  398. mov pf.off,ax
  399. or dx,ax
  400. push dx
  401. mov ax,fh
  402. cmp ax,-1
  403. jz sm_nothing_to_close
  404. cCall _lclose,<ax>
  405. sm_nothing_to_close:
  406. pop dx
  407. mov es,hExe
  408. assumes es,nothing
  409. test es:[ne_flags],NENOTP
  410. jnz start_library
  411. or dx,dx
  412. jz nothing_to_start
  413. cCall GetStackPtr,<es>
  414. cCall StartTask,<hPrev,hExe,dx,ax,pf>
  415. jmps sm_ret
  416. start_library:
  417. mov es, hExe
  418. or es:[ne_flags], NEWEPME ; Need to call my WEP on exit
  419. cCall StartLibrary,<hExe,lpPBlock,pf>
  420. jmps sm_ret
  421. nothing_to_start:
  422. mov ax,hExe
  423. test es:[ne_flags],NENOTP
  424. jnz sm_ret
  425. xor ax,ax
  426. sm_ret:
  427. cEnd
  428. if 0 ; too late to include in 3.1, add for next Windows release (donc)
  429. cProc GetProcAddressRes, <PUBLIC, FAR>, <ds, si, di>
  430. parmW hExe
  431. parmD pname ; pass in Pascal string
  432. cBegin
  433. les di, [pname] ; ES:DI = name to find
  434. mov cx, 255 ; CH = 0
  435. xor ax, ax
  436. push di
  437. repne scasb
  438. pop di
  439. jnz GPAR_fail
  440. not cl
  441. dec cl
  442. mov al, cl ; AX = length of name
  443. mov ds, [hExe] ; DS:SI = res name table
  444. mov bx, ds:[ne_restab] ; (actually DS:BX first time through)
  445. GPAR_nextsym:
  446. mov si, bx ; next entry to check
  447. mov cl, [si] ; string length
  448. jcxz GPAR_fail
  449. lea bx, [si+3]
  450. add bx, cx ; BX points to next (last + len + 3)
  451. cmp cx, ax
  452. jnz GPAR_nextsym ; length diff - no match
  453. inc si ; skip length byte
  454. push di
  455. rep cmpsb
  456. pop di
  457. jnz GPAR_nextsym
  458. lodsw ; get ordinal number
  459. ;if KDEBUG
  460. ; cCall FarEntProcAddress,<ds,ax,1>
  461. ;else
  462. cCall FarEntProcAddress,<ds,ax> ; I hate conditional assembly....
  463. ;endif
  464. mov cx, ax
  465. or cx, dx
  466. jmps GPAR_exit
  467. GPAR_fail:
  468. xor ax, ax
  469. cwd
  470. GPAR_exit:
  471. cEnd
  472. endif
  473. ;-----------------------------------------------------------------------;
  474. ; CallWEP ;
  475. ; ;
  476. ; Call WEP of DLL if appropriate ;
  477. ; ;
  478. ; Arguments: ;
  479. ; HANDLE hExe = HEXE of module about to close ;
  480. ; WORD WEPVal = 0, 1 pass to WEP, 2 check for WEP ;
  481. ; ;
  482. ; Returns: ;
  483. ; AX = status ;
  484. ; ;
  485. ; Error Returns: ;
  486. ; AX = Not a DLL ;
  487. ; AX = No WEP ;
  488. ; AX = Module not started ;
  489. ;-----------------------------------------------------------------------;
  490. cProc CallWEP, <PUBLIC,FAR>, <ds>
  491. parmW hExe
  492. parmW WEPVal
  493. localV szExitProc,4
  494. localD pExitProc
  495. localW bogusIBMAppSp
  496. cBegin
  497. mov ds, hExe ; Robustify this!
  498. CWErr = 1
  499. mov ax, 1 ; exit code
  500. cmp ds:[ne_expver], 300h ; 3.0 libraries only
  501. jb CW_noWEP
  502. CWErr = CWErr+1
  503. inc ax
  504. test ds:[ne_flags], NENOTP ; is it a DLL?
  505. jz CW_noWEP
  506. CWErr = CWErr+1
  507. inc ax ; Font, etc
  508. cmp ds:[ne_cseg],0
  509. jz CW_noWEP
  510. CWErr = CWErr+1
  511. inc ax
  512. mov bx, ds:[ne_pautodata] ; Make sure auto data loaded
  513. or bx, bx
  514. jz @F
  515. test ds:[bx].ns_flags, NSLOADED
  516. jz CW_noWEP
  517. @@:
  518. CWErr = CWErr+1
  519. inc ax
  520. NoWepErr = CWErr
  521. mov [szExitProc].lo, 'EW' ; If the module has a procedure
  522. mov [szExitProc].hi, 'P' ; named 'WEP', call it.
  523. lea bx, szExitProc
  524. push ax
  525. cCall GetProcAddress, <ds, ss, bx>
  526. mov [pExitProc].off, ax
  527. mov [pExitProc].sel, dx
  528. or ax, dx
  529. pop ax
  530. jnz CW_WEP
  531. CW_noWEP:
  532. jmps CW_noWEP1
  533. CW_WEP:
  534. cmp WEPVAL,2 ; If I'm just looking for WEP
  535. jz CW_OK ; return 0
  536. inc ax
  537. test ds:[ne_flags], NEWEPME ; don't call wep if libmain
  538. jz CW_noWEP ; wasn't called
  539. and ds:[ne_flags], NOT NEWEPME ; only call WEP once
  540. SetKernelDSNRES ; Save old GP chaine
  541. pusha
  542. push lpGPChain.sel
  543. push lpGPChain.off
  544. push cs
  545. push offset cw_BlowChunks
  546. mov lpGPChain.sel, ss ; and insert self in the chain
  547. mov lpGPChain.off, sp
  548. UnSetKernelDS
  549. mov ax, ss
  550. mov ds, ax
  551. mov es, ax
  552. mov bogusIBMAppSP,sp ; Save sp cause some apps (Hollywood)
  553. ; don't retf 2 correctly when we
  554. ; call their wep
  555. cCall pExitProc, <WEPVal> ; fSystemExit
  556. mov sp,bogusIBMAppSp
  557. add sp, 4 ; remove the CS:IP for error handler
  558. cw_BlowChunks:
  559. SetKernelDSNRES
  560. pop lpGPChain.off ; restore GPChain
  561. pop lpGPChain.sel
  562. popa
  563. UnSetKernelDS
  564. CW_OK:
  565. xor ax, ax
  566. CW_noWEP1:
  567. cmp WEPVAL, 2 ; if we checked for whining
  568. jnz CW_done
  569. or ax, ax ; if we found, then OK
  570. jz CW_done
  571. cmp ax, NoWepErr ; anything other than NoWep is OK
  572. jz CW_done
  573. xor ax, ax
  574. CW_done:
  575. cEnd
  576. ;-----------------------------------------------------------------------;
  577. ; LoadModule ;
  578. ; ;
  579. ; Loads a module or creates a new instance of an existing module. ;
  580. ; ;
  581. ; Arguments: ;
  582. ; FARP p = name of module or handle of existing module ;
  583. ; FARP lpPBlock = Parameter Block to pass to CreateTask ;
  584. ; ;
  585. ; Returns: ;
  586. ; AX = instance handle or module handle ;
  587. ; ;
  588. ; Error Returns: ;
  589. ;LME_MEM = 0 ; Out of memory ;
  590. ;LME_FNF = 2 ; File not found
  591. ;LME_LINKTASK = 5 ; can't link to task ;
  592. ;LME_LIBMDS = 6 ; lib can't have multiple data segments ;
  593. ;LME_VERS = 10 ; Wrong windows version ;
  594. ;LME_INVEXE = 11 ; Invalid exe ;
  595. ;LME_OS2 = 12 ; OS/2 app ;
  596. ;LME_DOS4 = 13 ; DOS 4 app ;
  597. ;LME_EXETYPE = 14 ; unknown exe type ;
  598. ;LME_RMODE = 15 ; not a pmode windows app ;
  599. ;LME_APPMDS = 16 ; multiple data segments in app ;
  600. ;LME_EMS = 17 ; scum app in l-frame EMS ;
  601. ;LME_PMODE = 18 ; not an rmode windows app ;
  602. ;LME_INVCOMP = 20 ; invalid DLL caused fail of EXE load ;
  603. ;LME_PE32 = 21 ; Windows Portable EXE app - let them load it ;
  604. ;LME_MAXERR = 32 ; for comparisons ;
  605. ; ;
  606. ; Registers Preserved: ;
  607. ; DI, SI, DS ;
  608. ; Registers Destroyed: ;
  609. ; BX, CX, DX, ES ;
  610. ; ;
  611. ; Calls: ;
  612. ; AllocAllSegs ;
  613. ; CreateInsider ;
  614. ; DecExeUsage ;
  615. ; DelModule ;
  616. ; FindExeFile ;
  617. ; FindExeInfo ;
  618. ; FreeModule ;
  619. ; GetExePtr ;
  620. ; GetInstance ;
  621. ; GetStringPtr ;
  622. ; IncExeUsage ;
  623. ; LoadExeHeader ;
  624. ; LoadModule ;
  625. ; FarLoadSegment ;
  626. ; lstrlen ;
  627. ; FarMyFree ;
  628. ; MyOpenFile ;
  629. ; PreloadResources ;
  630. ; StartModule ;
  631. ; _lclose ;
  632. ; ;
  633. ; History: ;
  634. ; Sun 12-Nov-1989 14:19:04 -by- David N. Weise [davidw] ;
  635. ; Added the check for win87em. ;
  636. ; ;
  637. ; Fri 07-Apr-1989 23:15:42 -by- David N. Weise [davidw] ;
  638. ; Added support for task ExeHeaders above The Line in Large ;
  639. ; Frame EMS. ;
  640. ; ;
  641. ; Tue Oct 13, 1987 05:00:00p -by- David J. Habib [davidhab] ;
  642. ; Added check for FAPI applications. ;
  643. ; ;
  644. ; Sat Jul 18, 1987 12:04:15p -by- David N. Weise [davidw] ;
  645. ; Added support for multiple instances in different EMS banks. ;
  646. ; ;
  647. ; Tue Jan 01, 1980 06:57:01p -by- David N. Weise [davidw] ;
  648. ; ReWrote it from C into assembly. ;
  649. ; ;
  650. ; Wed Sep 17, 1986 03:31:06p -by- Charles Whitmer [chuckwh] ;
  651. ; Modified the original LoadModule code to only allow INSIDERs to ;
  652. ; allocate segments for a new process. An INSIDER is a new process ;
  653. ; stub which bootstraps up a new instance of an application. ;
  654. ;-----------------------------------------------------------------------;
  655. assumes ds,nothing
  656. assumes es,nothing
  657. cProc ILoadLibrary,<PUBLIC,FAR>
  658. parmD pLibName
  659. localV szExitProc,4
  660. cBegin
  661. mov ax,-1
  662. cCall <far ptr LoadModule>,<pLibName,ax,ax>
  663. cmp ax, LME_INVEXE ; Invalid format?
  664. jnz @F
  665. mov ax, LME_INVCOMP ; Invalid component
  666. @@:
  667. if KDEBUG
  668. SetKernelDSNRes
  669. cmp fBooting, 0
  670. jne ll_fail ; No check while booting
  671. cmp ax, LME_MAXERR
  672. jb ll_fail ; No library, so no WEP()
  673. push ax ; Now check for WEP
  674. cCall GetExePtr,<ax>
  675. mov es, ax
  676. test es:[ne_flags],NEPROT ; ignore for OS/2 apps
  677. jnz ll_noWhine
  678. cmp es:[ne_usage], 0
  679. jne ll_noWhine ; Only check on first load!
  680. push dx
  681. push ax
  682. cCall CallWEP,<ax,2> ; Just check for WEP, don't call it
  683. or ax, ax
  684. pop ax
  685. pop dx
  686. jz ll_noWhine
  687. trace_out "No WEP in library - > %AX0 %AX1"
  688. ; fkerror 0,<No WEP in library - >,ax,dx
  689. ll_noWhine:
  690. pop ax ; return value of LoadModule
  691. ll_fail:
  692. endif ; KDEBUG
  693. cEnd
  694. os2calls DB 'DOSCALLS' ; Used for FAPI detection
  695. mgxlib DB 'MGXLIB' ; Used for lib large entry table detection
  696. win87em DB 'WIN87EM.DLL',0 ; Used for win87em.exe detection
  697. assumes ds,nothing
  698. assumes es,nothing
  699. ?SAV5 = ?DOS5 ; Adobe Type Manager check the LoadModule
  700. ?DOS5 = 0 ; prolog and expects to see INC BP there...
  701. public LMAlreadyLoaded, LMLoadExeFile, LMCheckHeader, LMRamNMods
  702. public LMImports, LMSegs, LMLetsGo, LMPrevInstance, LMCleanUp
  703. cProc ILoadModule,<PUBLIC,FAR>,<di,si>
  704. parmD lpModuleName
  705. parmD lpPBlock
  706. localW fh ; close if failed
  707. localW pExe ; point to NE header in RAM
  708. ; localW hExe ; prev module if already loaded
  709. localW hResult ; temp return value
  710. localW hDepFail ; return of implicit link loads
  711. localW abortresult ; temp return value
  712. localW ffont ; flag if loading a *.fon
  713. localW fexe ; flag if loading a *.exe
  714. ifdef notyet
  715. localW dll ; flag if loading a *.dll
  716. endif
  717. localW hBlock ; fastload block from LoadExeHeader
  718. localW AllocAllSegsRet
  719. localW exe_type ; from LoadExeHeader
  720. localW hTDB ; dx from CloseApplEnv
  721. localW SavePDB ; save caller's pdb, switch to krnl's
  722. localW fWOA ; save flag if we're loading WOA
  723. if ROM
  724. localW selROMHdr
  725. localW fLoadFromDisk
  726. localW fReplaceModule
  727. endif
  728. ifdef WOW
  729. LocalD pszKnownDLLPath
  730. LocalW fKnownDLLOverride
  731. localW RefSelector
  732. localW LMHadPEDLL
  733. localW hPrevInstance ; previous 16-bit module handel with the same name
  734. endif
  735. localD FileOffset ; offset to start of ExeHdr
  736. localW OnHardDisk ; don't cache FH if on floppy
  737. localV namebuf,136 ; SIZE OPENSTRUC + 127
  738. localW fModCompatFlags ; used by LMRamNMods
  739. cBegin
  740. SetKernelDSNRES
  741. mov al,Kernel_Flags[1] ; solve re-entrancy #10759
  742. and ax,KF1_WINOLDAP
  743. mov fWOA,ax
  744. and Kernel_Flags[1],NOT KF1_WINOLDAP
  745. inc fLMdepth ; # current invocations
  746. ;** Log this entry only if in diagnostic mode
  747. mov ax, fDiagMode ; Only log if booting and diag mode
  748. and al, fBooting
  749. jz @F
  750. ;** Write out the string
  751. mov ax,dataOFFSET szLoadStart ; Write the string
  752. cCall DiagOutput, <ds,ax>
  753. push WORD PTR lpModuleName[2]
  754. push WORD PTR lpModuleName[0]
  755. cCall DiagOutput
  756. mov ax,dataOFFSET szCRLF
  757. cCall DiagOutput, <ds,ax>
  758. ; Zero out flags and handles
  759. @@:
  760. ifdef WOW
  761. mov LMHadPEDLL,0
  762. mov hPrevInstance,0
  763. lm_restart:
  764. endif
  765. xor ax,ax
  766. ; mov hExe,ax
  767. mov pExe,ax
  768. mov abortresult,ax ; default 0 == out of memory
  769. mov ffont,ax
  770. mov fexe,ax
  771. ifdef notyet
  772. mov dll,ax
  773. endif
  774. mov hBlock,ax
  775. mov hTDB,ax
  776. if ROM
  777. mov selROMHdr,ax
  778. mov fLoadFromDisk, ax ; PATCHING
  779. mov fReplaceModule, ax
  780. endif
  781. ; Some flags are default -1
  782. dec ax
  783. mov fh, ax
  784. mov SavePDB, ax
  785. ; First, see if we were passed in a handle in the filename
  786. les si,lpModuleName ; point to the file name
  787. mov ax,es
  788. or ax,ax ; Was a handle passed in low word?
  789. jnz @F
  790. cCall GetExePtr,<si> ; Valid handle?
  791. or ax, ax
  792. jnz prev_instance
  793. mov al, LME_FNF ; call this file not found??
  794. jmp ilm_ret
  795. ; No handle, see if filename is already loaded
  796. @@: call LMAlreadyLoaded ; es:si -> modname on stack
  797. cmp ax, LME_MAXERR
  798. jb @F ; Not found, try to load it
  799. ; a 16-bit module with the same name is loaded
  800. ; if module is being loaded is a dll, use the loaded instance
  801. ; else if module is being loaded is a task
  802. ; if it is a 32-bit task then load it from disk
  803. ; else use the loaded instance
  804. ifdef WOW
  805. mov hPrevInstance, ax ; store previous instance handle
  806. mov ax,lpPBlock.off ; check if this is a dll or a task
  807. and ax,lpPBlock.sel
  808. inc ax
  809. jnz @F ; non-zero means it is a task
  810. ; so check first if it is a 16-bit task
  811. prev_instance_16task:
  812. mov ax, hPrevInstance
  813. endif
  814. prev_instance:
  815. call LMPrevInstance
  816. jmp ilm_ret
  817. ; Wasn't loaded, see if we can load it
  818. @@: call LMLoadExeFile ; fh in DI, AX = 0 or error code
  819. or ax, ax
  820. jz @F
  821. jmp ilm_ret ; can't find it - return error
  822. @@:
  823. if ROM
  824. mov ax, di
  825. cmp di, -1
  826. jnz lm_disk_exe_header
  827. mov ax, selROMHdr
  828. lm_disk_exe_header:
  829. ; Here to deal with a new library or task module.
  830. ; We found the file, now load and scan the header
  831. @@: lea si,namebuf
  832. cCall LoadExeHeader,<ax,di,ss,si>
  833. cmp ax,LME_MAXERR
  834. jb ilm_ret
  835. cmp di, -1
  836. jnz lm_disk_header_loaded
  837. or es:[ne_flags], NEMODINROM
  838. lm_disk_header_loaded:
  839. else
  840. ; Here to deal with a new library or task module.
  841. ; We found the file, now load and scan the header
  842. @@: lea si,namebuf
  843. cCall LoadExeHeader,<di,di,ss,si>
  844. ifdef WOW
  845. cmp ax,LME_PE
  846. jne @F
  847. ; If we find the module is a Win32 binary (PE), check to see
  848. ; if we're trying to load a task or DLL. If it's a DLL
  849. ; we will continue searching for a Win16 copy of this DLL
  850. ; on the path. If we're unsuccessful we'll eventually
  851. ; munge the file not found error code back to LME_PE.
  852. mov ax,lpPBlock.off
  853. and ax,lpPBlock.sel
  854. inc ax
  855. mov ax,LME_PE
  856. jnz @F ; have a PBlock, must be doing LoadModule
  857. cmp LMHadPEDLL,0
  858. je lm_retry_pe
  859. mov LMHadPEDLL,0
  860. mov OFContinueSearch,0
  861. KernelLogError <DBF_WARNING>,ERR_LOADMODULE,"Found Win32 DLL again after continuing search."
  862. jmps ilm_ret
  863. @@: jmps @F
  864. lm_retry_pe:
  865. ; Tell OpenFile to restart last search at next search location.
  866. mov OFContinueSearch,1
  867. mov LMHadPEDLL,1
  868. KernelLogError <DBF_WARNING>,ERR_LOADMODULE,"Found Win32 DLL, continuing search for Win16 copy."
  869. ; Close open Win32 DLL file handle
  870. cCall My_lclose,<fh>
  871. ; Switch back to caller's PDB
  872. mov si, -1
  873. xchg si, SavePDB
  874. mov Win_PDB, si
  875. or fh, -1
  876. jmp lm_restart
  877. @@:
  878. endif
  879. cmp ax,LME_MAXERR
  880. jb ilm_ret
  881. endif
  882. ifdef WOW
  883. cmp hPrevInstance, 0 ; if there is a previous 16-bit task
  884. je @F ;
  885. cCall My_lclose,<fh> ; close opened file before invoking previous instance
  886. jmp prev_instance_16task
  887. endif
  888. ; Header is loaded, now see if valid for Windows
  889. @@: call LMCheckHeader
  890. cmp ax, LME_MAXERR
  891. jb ilm_ret
  892. ; Now allocate segs, check for special modules, etc
  893. @@: call LMRamNMods
  894. cmp ax, LME_MAXERR
  895. jb ilm_ret
  896. ; Load import libraries (scary code here)
  897. @@: call LMImports
  898. cmp ax, LME_MAXERR
  899. jb ilm_ret
  900. ; Load and relocate segments
  901. @@: call LMSegs
  902. cmp ax, LME_MAXERR
  903. jb ilm_ret
  904. ; Load resources, schedule execution
  905. @@: call LMLetsGo
  906. ; Everyone comes through ILM_RET - we free the fastload block, etc
  907. ilm_ret:
  908. call LMCleanUp
  909. jmp LoadModuleEnd
  910. abort_load0:
  911. pop fLMdepth
  912. abort_load:
  913. cmp fLMdepth, 1 ; If a recursive call, nothing
  914. jne abort_load_A ; has been incremented!
  915. cCall DecExeUsage,<pExe>
  916. abort_load_A:
  917. cCall My_lclose,<fh>
  918. mov es,pExe
  919. push es:[ne_flags]
  920. cCall DelModule,<es>
  921. mov pExe, 0
  922. pop bx
  923. abort_load_B: ; If app, close environment
  924. test bx,NENOTP
  925. jnz lm_ab
  926. mov si, -1
  927. xchg si, SavePDB ; Saved PDB?
  928. inc si
  929. jz @F ; nope.
  930. dec si
  931. mov Win_PDB, si ; yes, restore it
  932. @@:
  933. mov si, fLMdepth
  934. mov fLMdepth, 0
  935. cCall CloseApplEnv,<abortresult,es>
  936. mov fLMdepth, bx
  937. lm_ab: mov ax, abortresult
  938. retn
  939. ; add sp, 2
  940. ; jmps ilm_ret ; ax = abortresult. (0 normal, 11 fapi)
  941. ifdef WOW
  942. winspool db "WINSPOOL.EXE" ; Trying to Load Winspool ?
  943. size_winspool equ $-winspool
  944. db 0h ; NULL Terminate
  945. endif ;WOW
  946. ;----------------------------------------------------------------------
  947. ;
  948. ; LMAlreadyLoaded - internal routine for LoadModule
  949. ; See if a module is already loaded by looking for the file name
  950. ; or the module name.
  951. ; Entry:
  952. ; ES:SI points to filename
  953. ; Exit:
  954. ; AX = handle of previous instance
  955. ; SS:SI -> uppercase filename
  956. ; Error:
  957. ; AX = error value < LME_MAXERR
  958. ;
  959. ;-----------------------------------------------------------------------
  960. LMAlreadyLoaded:
  961. ; We check if this Module is already loaded. To do so we get the
  962. ; name off of the end of the string, omitting the extension.
  963. krDebugOut <DEB_TRACE OR DEB_KrLoadMod>, "Loading @ES:SI"
  964. cCall lstrlen,<es,si> ; Get the length of the string.
  965. or ax,ax ; NULL string?
  966. jnz @F
  967. mov al,LME_FNF ; return file not found error
  968. retn
  969. ifdef FE_SB
  970. ;
  971. ; Backword search '\' or ':' is prohibited for DBCS version of
  972. ; Windows. Some DBCS 2nd byte may have '\' or ':'. So we search
  973. ; these characters from beginning of string.
  974. ;
  975. @@:
  976. cld
  977. mov bx,si
  978. delinator_loop_DBC:
  979. lods byte ptr es:[si] ; fetch a character
  980. test al,al
  981. jz found_end_DBC
  982. cmp al,"\"
  983. jz found_delinator_DBC
  984. cmp al,'/'
  985. jz found_delinator_DBC
  986. cmp al,":"
  987. jz found_delinator_DBC
  988. call FarMyIsDBCSLeadByte ; see if char is DBC...
  989. jc delinator_loop_DBC
  990. inc si ; skip 2nd byte of DBC
  991. jmp delinator_loop_DBC
  992. found_delinator_DBC:
  993. mov bx,si ; update delinator pointer
  994. if ROM
  995. inc fLoadFromDisk ; PATCHING
  996. endif
  997. jmp delinator_loop_DBC
  998. found_end_DBC:
  999. mov si, bx ; ES:SI -> beginning of name..
  1000. else
  1001. @@: mov cx,ax
  1002. add si,ax
  1003. dec si ; ES:SI -> end of string
  1004. std
  1005. delineator_loop: ; look for beginning of name
  1006. lods byte ptr es:[si]
  1007. cmp al,"\"
  1008. jz found_delineator
  1009. cmp al,'/'
  1010. jz found_delineator
  1011. cmp al,":"
  1012. jz found_delineator
  1013. loop delineator_loop
  1014. dec si
  1015. if ROM
  1016. dec fLoadFromDisk ;PATCHING
  1017. endif
  1018. found_delineator: ; ES:SI -> before name
  1019. if ROM
  1020. inc fLoadFromDisk ;PATCHING
  1021. endif
  1022. cld
  1023. inc si
  1024. inc si ; ES:SI -> beginning of name
  1025. endif
  1026. xor di,di
  1027. xor bx,bx
  1028. copy_name_loop:
  1029. lods byte ptr es:[si] ; Copy and capitalize to temp buffer.
  1030. or al,al
  1031. jz got_EXE_name
  1032. cmp al,"."
  1033. jne @F
  1034. lea bx,namebuf[di]
  1035. ifdef notyet
  1036. cmp dll, 0 ; Was it .DLL and failed to open it?
  1037. jz @F ; no, no hacking
  1038. mov byte ptr es:[si], 'E' ; yes, change it to .EXE
  1039. mov word ptr es:[si+1],'EX'
  1040. mov dll, 0
  1041. endif
  1042. @@:
  1043. ifdef FE_SB
  1044. ;
  1045. ; Do not capitalize if a character is DBC.
  1046. ;
  1047. call FarMyIsDBCSLeadByte
  1048. jnc @F
  1049. call FarMyUpper ; capitalize if SBC..
  1050. jmps is_a_SBC
  1051. @@:
  1052. mov namebuf[di],al
  1053. inc di
  1054. lods byte ptr es:[si] ; copy 2nd byte also
  1055. is_a_SBC:
  1056. mov namebuf[di],al
  1057. else
  1058. call FarMyUpper
  1059. mov namebuf[di],al
  1060. endif
  1061. inc di
  1062. jmps copy_name_loop
  1063. ; Finally call FindExeInfo to see if it's already loaded!
  1064. got_EXE_name:
  1065. cmp namebuf[di][-2],'NO' ; .fons are allowed to be
  1066. jnz @F ; non protect mode
  1067. cmp namebuf[di][-4],'F.'
  1068. jnz @F
  1069. mov ffont,bp ; make non-zero
  1070. @@:
  1071. cmp namebuf[di][-2],'EX' ; .exes will not get
  1072. jnz @F ; prompted
  1073. cmp namebuf[di][-4],'E.'
  1074. jnz @F
  1075. mov fexe,bp ; make non-zero
  1076. @@:
  1077. ifdef NOTYET
  1078. cmp namebuf[di][-2],'LL'
  1079. jne @F
  1080. cmp namebuf[di][-4],'D.'
  1081. jne @F
  1082. mov dll, di
  1083. @@:
  1084. endif
  1085. ifdef WOW
  1086. ; apps will expect to find WINSPOOL.DRV, which is a 32-bit driver.
  1087. ; we need to intercept this and change it WINSPOOL.EXE, which is our 16-bit
  1088. ; stub that contains a few entrypoints.
  1089. if 0
  1090. ; Bitstreams's MakeUp extracts the printer driver from the [devices]
  1091. ; section of win.ini the line looks like this:
  1092. ; HP Laserjet Series II=winspool,FILE:
  1093. ; and then it calls LoadLibrary(drivername) ie LoadLibrary("winspool")
  1094. ; so we need to allow no extension when checking for "winspool"
  1095. endif
  1096. cmp namebuf[di][-2],'VR'
  1097. jne checkfornoext
  1098. cmp namebuf[di][-4],'D.'
  1099. jne @f
  1100. jmp short gotadrv
  1101. checkfornoext:
  1102. ; int 3
  1103. cmp di,8
  1104. jc @f
  1105. cmp namebuf[di][-2],'LO'
  1106. jne @f
  1107. cmp namebuf[di][-4],'OP'
  1108. jne @f
  1109. cmp namebuf[di][-6],'SN'
  1110. jne @f
  1111. cmp namebuf[di][-8],'IW'
  1112. jne @f
  1113. ; the last 8 characters are 'WINSPOOL'. tack on '.EXE' and proceed.
  1114. add di,4
  1115. mov namebuf[di][-2],'EX' ; Changed Uppercased String
  1116. mov namebuf[di][-4],'E.'
  1117. push cx
  1118. mov lpModuleName.hi,cs
  1119. lea cx,winspool ;
  1120. mov lpModuleName.lo,cx
  1121. pop cx
  1122. jmp short @f
  1123. gotadrv:
  1124. push es
  1125. push ds
  1126. push si
  1127. push cx
  1128. push di
  1129. smov es,ss
  1130. lea di,namebuf[di][-(size_winspool)]
  1131. smov ds,cs
  1132. lea si,winspool
  1133. mov cx,size_winspool-4 ; match WINSPOOL?
  1134. rep cmpsb
  1135. pop di
  1136. jnz not_winspool
  1137. mov namebuf[di][-2],'EX' ; Changed Uppercased String
  1138. mov namebuf[di][-4],'E.'
  1139. mov lpModuleName.hi,cs ; Used by Myopenfile below
  1140. lea cx,winspool ;
  1141. mov lpModuleName.lo,cx
  1142. not_winspool:
  1143. pop cx
  1144. pop si
  1145. pop ds
  1146. pop es
  1147. @@:
  1148. endif; WOW
  1149. mov namebuf[di],al ; Null terminate file name
  1150. lea si,namebuf
  1151. push bx
  1152. cCall FindExeFile,<ss,si>
  1153. pop bx
  1154. or ax,ax
  1155. jnz al_end
  1156. or bx,bx ; extension specified?
  1157. jz @F ; No, DI correct then
  1158. sub bx,si ; DI = length of name portion
  1159. mov di,bx
  1160. @@:
  1161. cCall FindExeInfo,<ss,si,di>
  1162. al_end:
  1163. retn
  1164. ;----------------------------------------------------------------------
  1165. ;
  1166. ; LMLoadExeFile - internal routine for LoadModule
  1167. ; Try to open an EXE file
  1168. ; Enter:
  1169. ; SS:SI -> uppercase filename
  1170. ; Exit:
  1171. ; AX=0
  1172. ; DI = fh = handle of open EXE file
  1173. ; Error:
  1174. ; AX = error code
  1175. ; Effects:
  1176. ; Set Win_PDB to kernel PDB to open the file
  1177. ;
  1178. ;-----------------------------------------------------------------------
  1179. ; if here then not yet loaded, see if we can open the file
  1180. LMLoadExeFile:
  1181. if ROM
  1182. cCall <far ptr FindROMExe>,<ss,si> ; Module exist in ROM?
  1183. mov selROMHdr,ax ; selector mapping ROM
  1184. or ax,ax ; copy of EXE header if yes
  1185. jz @F
  1186. ; PATCHING
  1187. cmp fLoadFromDisk, 0 ; Loading this from disk? If so, go
  1188. jz in_rom
  1189. @@: jmp not_in_rom ; do it, but remember selROMHdr
  1190. ; cause that's what we're patching
  1191. in_rom:
  1192. smov es,ss ; LoadExeHeader expects an OPENSTRUC
  1193. cCall lstrlen,<es,si> ; containing the module file name.
  1194. add si,ax ; namebuf (ss:si) already contains
  1195. .erre opFile ; a capitalized name string, shift
  1196. lea di,[si].opFile ; it down to make room for the other
  1197. mov bx,di ; OPENSTRUC fields.
  1198. mov cx,ax
  1199. inc cx
  1200. std
  1201. rep movs byte ptr es:[di],es:[si] ; I don't think this is safe!
  1202. .errnz opLen
  1203. lea si,namebuf ; Now set the length field, doesn't
  1204. sub bx,si ; include terminating null
  1205. mov es:[si].opLen,bl
  1206. .erre opFile-1
  1207. lea di,[si.opLen+1] ; Zero out fields between length and
  1208. mov cx,opFile-1 ; the file name
  1209. xor al,al
  1210. cld
  1211. rep stosb
  1212. mov di,-1 ; no file handle in di
  1213. sub ax, ax ; 0 => success
  1214. retn
  1215. not_in_rom:
  1216. endif
  1217. mov ax, topPDB
  1218. xchg Win_PDB, ax ; Switch to Kernel's PDB,
  1219. mov SavePDB, ax ; saving current PDB
  1220. xor ax,ax
  1221. ifdef notyet
  1222. cmp dll, ax ; Don't prompt for .DLL, if it fails we
  1223. jnz @F ; try for .EXE which we will prompt for
  1224. endif
  1225. cmp fexe,ax ; Don't prompt for EXE file
  1226. jnz @F
  1227. mov ax,OF_CANCEL ; If DLL, let them cancel
  1228. mov es,curTDB
  1229. test es:[TDB_ErrMode],08000h ; did app say not to prompt??
  1230. jnz @F
  1231. mov ax,OF_CANCEL or OF_PROMPT
  1232. @@:
  1233. if SHARE_AWARE
  1234. or ax, OF_NO_INHERIT or OF_SHARE_DENY_WRITE
  1235. else
  1236. or ax, OF_NO_INHERIT
  1237. endif
  1238. ifdef WOW
  1239. ; Ask WOW32 to check the filename to see if it is
  1240. ; a Known DLL,
  1241. ;
  1242. ; If it is, WowIsKnownDLL will point pszKnownDLLPath
  1243. ; at a just-allocated buffer with the full path to
  1244. ; the DLL in the system32 directory and return with
  1245. ; AX nonzero. This buffer must be freed with a
  1246. ; call to WowIsKnownDLL with the filename pointer
  1247. ; zero, and pszKnownDLLPath as it was left by the
  1248. ; first call to WowIsKnownDLL.
  1249. ;
  1250. ; If it's not a known DLL, pszKnownDLLPath will be
  1251. ; NULL and AX will be zero.
  1252. push ax
  1253. cmp fBooting,0 ; Known DLLs take effect
  1254. je lef_look_for_known_dll ; after booting is complete.
  1255. mov fKnownDLLOverride,0 ; We're booting, make sure
  1256. jmps lef_dll_not_known ; we know not to call
  1257. ; WowIsKnownDLL the second time.
  1258. lef_look_for_known_dll:
  1259. push si
  1260. smov es,ss
  1261. lea bx,pszKnownDLLPath
  1262. cCall WowIsKnownDLL,<lpModuleName,esbx>
  1263. mov fKnownDLLOverride,ax
  1264. cmp ax,0
  1265. pop si
  1266. je lef_dll_not_known
  1267. pop ax
  1268. cCall MyOpenFile,<pszKnownDLLPath,ss,si,ax>
  1269. jmps @f
  1270. lef_dll_not_known:
  1271. pop ax
  1272. cCall MyOpenFile,<lpModuleName,ss,si,ax>
  1273. @@:
  1274. else
  1275. cCall MyOpenFile,<lpModuleName,ss,si,ax>
  1276. endif
  1277. ifdef notyet
  1278. mov di, dll
  1279. or di, di
  1280. jz no_second_chance
  1281. cmp ax, -1
  1282. jne no_second_chance ; open succeeded
  1283. xchg ax, SavePDB ; Restore original PDB (AX == -1)
  1284. mov Win_PDB, ax
  1285. les si, lpModuleName
  1286. pop ax
  1287. jmp pointer_to_name ; Start again!
  1288. no_second_chance:
  1289. endif
  1290. xor dh, dh
  1291. mov dl, ss:[si].opDisk
  1292. mov OnHardDisk, dx
  1293. mov fh,ax
  1294. mov di,ax ; DI gets preserved, AX doesn't!
  1295. inc ax ; -1 means error or invalid parsed file
  1296. mov ax, 0
  1297. jnz @F ; OK, return 0
  1298. ; MyOpenFile failed
  1299. mov ax,ss:[si].[opXtra] ; SI = &namebuf
  1300. or ax,ax ; What is the error value?
  1301. jnz @F
  1302. mov ax,LME_FNF ; unknown, call it file not found
  1303. @@:
  1304. ifdef WOW
  1305. push ax
  1306. mov ax,fKnownDLLOverride
  1307. cmp ax,0
  1308. je lef_no_need_to_free
  1309. push bx
  1310. push dx
  1311. push di
  1312. smov es,ss
  1313. lea bx,pszKnownDLLPath
  1314. cCall WowIsKnownDLL, <0,0,esbx>
  1315. pop di
  1316. pop dx
  1317. pop bx
  1318. lef_no_need_to_free:
  1319. pop ax
  1320. endif
  1321. retn
  1322. ;----------------------------------------------------------------------
  1323. ;
  1324. ; LMCheckHeader - internal routine for LoadModule
  1325. ; Loading new module - see if header values are OK
  1326. ; Enter:
  1327. ; ax = exeheader in RAM
  1328. ; bx = 0 or FastLoad ram block selector
  1329. ; cx = file offset of header
  1330. ; dx = exe_type
  1331. ; Exit:
  1332. ;
  1333. ;
  1334. ;-----------------------------------------------------------------------
  1335. LMCheckHeader:
  1336. mov exe_type,dx
  1337. mov hBlock,bx ; fast-load block
  1338. mov pExe,ax ; exeheader in RAM
  1339. mov es,ax
  1340. mov ax, cx ; file offset of header
  1341. mov cx, es:[ne_align]
  1342. mov bx, ax ; BX:AX <= AX shl CL
  1343. shl ax, cl
  1344. neg cl
  1345. add cl, 16
  1346. shr bx, cl
  1347. mov FileOffset.sel, bx
  1348. mov FileOffset.off, ax
  1349. if ROM
  1350. test es:[ne_flags], NEMODINROM
  1351. jnz @F
  1352. cmp selROMHdr, 0
  1353. jnz ch_patch_file
  1354. @@: jmp ch_not_patch_file
  1355. ch_patch_file:
  1356. test es:[ne_flagsothers], NEGANGLOAD
  1357. jnz ch_replace_mod
  1358. if 0
  1359. ; ack: loadexeheader trashes this...
  1360. mov ax, es:[ne_cseg]
  1361. mov ah, 2
  1362. cmp ax, es:[ne_gang_start]
  1363. endif
  1364. jz ch_check_rom_header
  1365. ; here for a replacement file with matching file name
  1366. ch_replace_mod:
  1367. inc fReplaceModule
  1368. jmp ch_not_patch_file
  1369. ch_check_rom_header:
  1370. push ds
  1371. push si
  1372. mov cx, es:[ne_cseg]
  1373. mov ds, selROMHdr
  1374. ; make sure that the various patching flags match up to
  1375. ; what they are supposed to be
  1376. ; RIB clears this bit, check
  1377. test ds:[ne_flagsothers], NEGANGLOAD
  1378. jnz ch_patch_error
  1379. ; does it have a patch table
  1380. test byte ptr ds:[ne_gang_start+1], 1
  1381. jnz ch_is_patchable
  1382. ; if no one links to this file, its ok, don't need to patch
  1383. test byte ptr ds:[ne_gang_start+1], 4
  1384. jnz ch_patch_error
  1385. ch_not_really_a_patch_file:
  1386. pop si
  1387. pop ds
  1388. jmp ch_not_patch_file
  1389. ch_patch_error:
  1390. pop si
  1391. pop ds
  1392. mov ax, LME_INVEXE
  1393. retn
  1394. ch_is_patchable:
  1395. ; must be the right segment
  1396. mov ax, ds:[ne_cseg]
  1397. cmp al, byte ptr ds:[ne_gang_start]
  1398. jnz ch_patch_error
  1399. ch_whack_segment_table:
  1400. mov si, ds:[ne_segtab]
  1401. mov bx, es:[ne_segtab]
  1402. ch_ps_patch_loop:
  1403. test es:[bx].ns_flags, NSINROM
  1404. jz ch_patch_loop_pass
  1405. mov ax, ds:[si].ns_flags
  1406. and ax, NSCOMPR or NSRELOC or NSLOADED or NSALLOCED
  1407. or es:[bx].ns_flags, ax
  1408. mov ax, ds:[si].ns_cbseg
  1409. mov es:[bx].ns_cbseg, ax
  1410. mov ax, ds:[si].ns_minalloc
  1411. mov es:[bx].ns_minalloc, ax
  1412. mov ax, ds:[si].ns_sector
  1413. mov es:[bx].ns_sector, ax
  1414. test es:[bx].ns_flags, NSLOADED
  1415. jz ch_patch_loop_pass
  1416. cmp es:[bx].ns_handle, 0
  1417. jnz ch_patch_loop_pass
  1418. mov es:[bx].ns_handle, ax
  1419. ch_patch_loop_pass:
  1420. add si, size new_seg
  1421. add bx, size new_seg1
  1422. loop ch_ps_patch_loop
  1423. pop si
  1424. pop ds
  1425. ch_not_patch_file:
  1426. endif
  1427. ; Is this module PMode-compatible?
  1428. cmp es:[ne_expver],300h ; by definition
  1429. jae @F
  1430. test dh,NEINPROT ; by flag
  1431. jnz @F
  1432. cmp ffont,0 ; are we loading a font?
  1433. jnz @F
  1434. mov cx,ss
  1435. lea bx,namebuf
  1436. call WarnRealMode
  1437. cmp ax,IDCANCEL
  1438. jnz @F ; yes, user says so
  1439. mov ax, LME_RMODE ; no, die you pig
  1440. retn
  1441. ifdef WOW
  1442. @@:
  1443. ;
  1444. ; if WOA invoked by app (not fWOA) fail it
  1445. ;
  1446. cmp fWOA,0 ; fWOA
  1447. jnz @F
  1448. cld
  1449. push si
  1450. push di
  1451. mov di, es:[ne_restab]
  1452. inc di
  1453. mov si, dataOffset WOAName
  1454. mov cx, 4
  1455. repe cmpsw
  1456. pop di
  1457. pop si
  1458. jnz @F
  1459. mov ax, LME_WOAWOW32
  1460. retn
  1461. endif
  1462. ; Are we dynalinking to a task?
  1463. @@:
  1464. test es:[ne_flags],NENOTP
  1465. jnz ch_not_a_process
  1466. or es:[ne_flags],NEINST ; for safety sake
  1467. mov ax,lpPBlock.off
  1468. and ax,lpPBlock.sel
  1469. inc ax
  1470. jnz ch_new_application ; not linking
  1471. mov ax, LME_LINKTASK
  1472. retn
  1473. ; Error if multiple instance EXE is a library module.
  1474. ch_not_a_process:
  1475. mov ax, 33 ; Any value > 32
  1476. test es:[ne_flags],NEPROT ; is it an OS/2 exe?
  1477. jnz ch_ok ; windows doesn't do this right
  1478. test es:[ne_flags],NEINST
  1479. jz ch_ok
  1480. mov ax, LME_LIBMDS ; I think this error code is wrong
  1481. ch_ok:
  1482. retn
  1483. ; Create environment for new application task.
  1484. ch_new_application:
  1485. call LMCheckHeap
  1486. or ax,ax
  1487. jz @F
  1488. cCall OpenApplEnv,<lpPBlock,pExe,fWOA>
  1489. mov es,pExe
  1490. or ax,ax ; AX is a selector, therefor > 32
  1491. jnz ch_ok
  1492. @@:
  1493. jmp abort_load_A
  1494. ;----------------------------------------------------------------------
  1495. ;
  1496. ; LMRamNMods - internal routine for LoadModule
  1497. ; Load segments, check for special modules
  1498. ; Enter:
  1499. ; EX = pexe
  1500. ; Exit:
  1501. ; CX = number of import modules
  1502. ; AX = status
  1503. ;
  1504. ;
  1505. ;-----------------------------------------------------------------------
  1506. LMRamNMods:
  1507. push es
  1508. cCall AddModule,<pExe>
  1509. pop es
  1510. or ax,ax
  1511. jnz @F
  1512. push es:[ne_flags] ; AddModule failed - out of memory
  1513. mov dx,ne_pnextexe
  1514. mov bx,dataOffset hExeHead
  1515. call FarUnlinkObject
  1516. pop bx
  1517. jmp abort_load_B ; clean this up
  1518. @@:
  1519. cmp es:[ne_expver],400h
  1520. jae rm_skip_modulecompat
  1521. ; Look for Module in ModuleCompatibilty section
  1522. ; and get its compat flags
  1523. push es ; save es
  1524. push ds
  1525. push dataoffset szModuleCompatibility
  1526. push es
  1527. mov bx,es:[ne_restab] ; module name is 1st rsrc
  1528. inc bx ; Skip length byte
  1529. push bx
  1530. xor ax, ax
  1531. push ax ; default = 0
  1532. call GetProfileInt
  1533. @@:
  1534. pop es ; restore es
  1535. ; Set the module's patch bit if the INI file says to.
  1536. if KDEBUG
  1537. test es:[ne_flagsothers], NEHASPATCH
  1538. jz @F
  1539. push ax
  1540. mov ax, es:[ne_restab]
  1541. inc ax
  1542. krDebugOut DEB_TRACE,"ILoadModule: module patch bit for @es:ax already set, clearing it"
  1543. pop ax
  1544. @@:
  1545. endif
  1546. and es:[ne_flagsothers], not NEHASPATCH ; clear module patch bit
  1547. ifdef WOW_x86
  1548. test ax, MCF_MODPATCH + MCF_MODPATCH_X86
  1549. else
  1550. test ax, MCF_MODPATCH + MCF_MODPATCH_RISC
  1551. endif
  1552. jz rm_after_modpatch
  1553. if KDEBUG
  1554. push ax
  1555. mov ax, es:[ne_restab]
  1556. inc ax
  1557. krDebugOut DEB_WARN,"ILoadModule: setting module patch bit for @es:ax"
  1558. pop ax
  1559. endif
  1560. or es:[ne_flagsothers], NEHASPATCH
  1561. rm_after_modpatch:
  1562. ; See if we need to make the module's segments not discardable
  1563. test ax, MCF_NODISCARD
  1564. jz rm_after_nodiscard
  1565. mov cx, es:[ne_cseg] ; cx = number of segs
  1566. jcxz rm_after_nodiscard
  1567. mov bx, es:[ne_segtab] ; es:bx = seg table start
  1568. rm_loop:
  1569. and es:[bx].ns_flags, not NSDISCARD ; clear the discard flag
  1570. add bx, SIZE NEW_SEG1 ; es:bx = seg table next entry
  1571. loop rm_loop
  1572. rm_after_nodiscard:
  1573. rm_skip_modulecompat:
  1574. mov bx, -1
  1575. if ROM
  1576. cmp bx,fh
  1577. jz @F
  1578. endif
  1579. cCall FarGetCachedFileHandle,<es,bx,fh> ; Set file handle cache up
  1580. mov fh, bx ; Use cached file handle from now
  1581. xchg SavePDB, bx ; Back to original PDB (BX == -1)
  1582. mov Win_PDB, bx
  1583. @@: xor bx,bx
  1584. mov hDepFail,-1 ; Assume success
  1585. mov cx,es:[bx].ne_cmod
  1586. jcxz @F
  1587. test kernel_flags,KF_pUID ; All done booting?
  1588. jnz @F ; Yes
  1589. or es:[bx].ne_flags,NEALLOCHIGH ; No, GDI and USER are party
  1590. ; dynlinks that can alloc high
  1591. @@: xor ax,ax
  1592. IFNDEF NO_APPLOADER
  1593. test es:[ne_flags],NEAPPLOADER
  1594. jnz rm_no_segs_to_alloc
  1595. ENDIF
  1596. cmp ax,es:[ne_cseg]
  1597. jz rm_no_segs_to_alloc
  1598. push es
  1599. mov es:[ne_usage],1
  1600. cCall AllocAllSegs,<es> ; AX is count of segs
  1601. pop es
  1602. mov es:[ne_usage],8000h
  1603. inc ax
  1604. jnz @F
  1605. jmp abort_load
  1606. @@:
  1607. dec ax
  1608. rm_no_segs_to_alloc:
  1609. mov AllocAllSegsRet, ax
  1610. xor bx, bx
  1611. mov di,es:[bx].ne_modtab ; ES:DI = pModIdx
  1612. mov cx,es:[bx].ne_cmod
  1613. or cx,cx
  1614. jz lm_ret_ok
  1615. ; this small chunk of code goes thru the imported names table
  1616. ; and looks for DOSCALLS. if DOSCALLS is found, then the app
  1617. ; is an FAPI "bound" application and not a windows app, and
  1618. ; loadmodule should return an error for "invalid format".
  1619. ; This will force it to run in a DOS box
  1620. ; coming in:
  1621. ; cx = cmod
  1622. ; di = modtab
  1623. test es:[bx].ne_flags,NENOTP ; only test apps, not libraries.
  1624. jnz lm_ret_ok
  1625. mov ax,exe_type ; UNKNOWN may be OS/2 in disguise.
  1626. cmp al,NE_UNKNOWN
  1627. jnz @F
  1628. push ds
  1629. smov ds,cs
  1630. mov ax,8
  1631. mov si,NRESCODEoffset os2calls ; DS:SI = "DOSCALLS"
  1632. call search_mod_dep_list
  1633. pop ds
  1634. jnc @F
  1635. mov abortresult,LME_INVEXE ; store invalid format code for return
  1636. jmp abort_load
  1637. ; In order to make it easier on our ISV to migrate to pmode
  1638. ; we must deal with win87em specially because the win 2.x
  1639. ; version gp faults. Since we have never shipped them a clean
  1640. ; one to ship with their apps we must compensate here.
  1641. ; If we are loading a win 2.x app in pmode we force the load
  1642. ; of win87em.dll. For compatibility in real mode we just load
  1643. ; the one they would have gotten anyway.
  1644. @@: cmp es:[bx].ne_expver,300h ; no special casing win3.0 apps
  1645. jae rm_no_win87em_here
  1646. push ds
  1647. smov ds,cs
  1648. mov ax,7
  1649. mov si,NRESCODEoffset win87em ; DS:SI = "WIN87EM"
  1650. call search_mod_dep_list
  1651. pop ds
  1652. jnc rm_no_win87em_here
  1653. push bx ; Load Win87em.dll
  1654. push es
  1655. cCall ILoadLibrary,<cs,si>
  1656. cmp ax,LME_MAXERR
  1657. jae @F
  1658. mov hDepFail,ax
  1659. @@: pop es
  1660. pop bx
  1661. rm_no_win87em_here:
  1662. lm_ret_ok:
  1663. mov di,es:[bx].ne_modtab ; ES:DI = pModIdx
  1664. mov cx,es:[bx].ne_cmod ; What is AX?
  1665. mov ax, es
  1666. retn
  1667. ;----------------------------------------------------------------------
  1668. ;
  1669. ; LMImports - internal routine for LoadModule
  1670. ;
  1671. ;-----------------------------------------------------------------------
  1672. LMImports:
  1673. or cx, cx
  1674. jnz im_inc_dependencies_loop
  1675. jmp im_end_dependency_loop
  1676. im_inc_dependencies_loop:
  1677. push cx
  1678. mov si,es:[di]
  1679. push es
  1680. or si,si
  1681. jz im_next_dependencyj
  1682. add si,es:[ne_imptab] ; ES:SI = pname
  1683. xor ax,ax
  1684. mov al,es:[si] ; get length of name
  1685. inc si
  1686. mov cx, ax
  1687. mov bx, es ; pExe
  1688. ;;;; Load the imported library.
  1689. push ds ; Copy the name and .EXE to namebuf
  1690. push di
  1691. smov es,ss
  1692. mov ds,bx
  1693. UnSetKernelDS
  1694. lea di,namebuf
  1695. mov bx,di
  1696. cld
  1697. rep movsb
  1698. mov byte ptr es:[di], 0 ; Null terminate
  1699. push bx
  1700. push es
  1701. cCall GetModuleHandle,<es,bx>
  1702. pop es
  1703. pop bx
  1704. or ax, ax
  1705. jz @F
  1706. pop di
  1707. pop ds
  1708. jmps im_imported_exe_already_loaded
  1709. @@: cmp ds:[ne_expver], 300h ; USE .DLL for 3.0, .EXE for lower
  1710. jae im_use_dll
  1711. mov es:[di][0],"E."
  1712. mov es:[di][2],"EX"
  1713. jmps im_done_extension
  1714. im_use_dll:
  1715. mov word ptr ss:[di][0],"D."
  1716. mov word ptr ss:[di][2],"LL"
  1717. im_done_extension:
  1718. mov byte ptr es:[di][4],0
  1719. pop di
  1720. pop ds
  1721. ResetKernelDS
  1722. cCall ILoadLibrary,<ss,bx>
  1723. cmp ax,LME_MAXERR
  1724. jae im_imported_exe_loaded
  1725. mov hDepFail,ax
  1726. xor ax,ax
  1727. im_next_dependencyj:
  1728. jmps im_next_dependency
  1729. im_imported_exe_already_loaded:
  1730. ;;; push ax
  1731. ;;; cCall IncExeUsage,<ax>
  1732. ;;; pop ax
  1733. im_imported_exe_loaded:
  1734. cCall GetExePtr,<ax>
  1735. mov es,ax
  1736. assumes es,nothing ; assume that dep libraries
  1737. or es:[ne_flags],NEALLOCHIGH ; are smart
  1738. im_next_dependency:
  1739. pop es
  1740. assumes es,nothing
  1741. mov es:[di],ax
  1742. inc di
  1743. inc di
  1744. pop cx
  1745. dec cx
  1746. jz im_end_dependency_loop
  1747. jmp im_inc_dependencies_loop
  1748. im_end_dependency_loop:
  1749. mov es:[ne_usage], 0
  1750. cmp fLMdepth, 1
  1751. jne @F
  1752. push es ; Now set usage count of this
  1753. cCall IncExeUsage,<es> ; module and dependants
  1754. pop es
  1755. @@:
  1756. mov cx,hDepFail
  1757. inc cx
  1758. jz im_libs_ok
  1759. dec cx
  1760. mov abortresult,cx
  1761. im_abort_loadj:
  1762. jmp abort_load
  1763. im_libs_ok:
  1764. retn
  1765. ;----------------------------------------------------------------------
  1766. ;
  1767. ; LMSegs - internal routine for LoadModule
  1768. ;
  1769. ;-----------------------------------------------------------------------
  1770. LMSegs:
  1771. ; Do something about all those segments in the module.
  1772. IFNDEF NO_APPLOADER
  1773. test es:[ne_flags],NEAPPLOADER
  1774. jz @F
  1775. ;* * special boot for AppLoader
  1776. push Win_PDB
  1777. push fLMdepth
  1778. mov fLMdepth, 0
  1779. mov ax, -1
  1780. cCall FarGetCachedFileHandle,<es,ax,ax>
  1781. Save <es>
  1782. cCall BootAppl,<es, ax> ;* returns BOOL
  1783. cCall FlushCachedFileHandle,<es>
  1784. pop fLMdepth
  1785. pop Win_PDB
  1786. or ax,ax
  1787. jnz lms_done
  1788. jmp abort_load
  1789. ; retn
  1790. @@:
  1791. ENDIF ;!NO_APPLOADER
  1792. mov cx, AllocAllSegsRet
  1793. jcxz lms_done
  1794. lms_preload_segments:
  1795. mov si,es:[ne_segtab] ; ES:SI = pSeg
  1796. mov cx,es:[ne_cseg]
  1797. xor di,di
  1798. lms_ps_loop:
  1799. inc di
  1800. if ROM
  1801. mov bx,es:[si].ns_flags ; Load the segment now if it's execute
  1802. and bx,NSINROM OR NSLOADED ; in place in the ROM.
  1803. cmp bx,NSINROM OR NSLOADED
  1804. je lms_ReadFromRom
  1805. endif
  1806. test es:[si].ns_flags,NSPRELOAD
  1807. jz lms_next_segment
  1808. if ROM
  1809. test byte ptr es:[si].ns_flags+1,(NSINROM SHR 8)
  1810. jnz lms_ReadFromRom
  1811. endif
  1812. cmp es:[ne_align], 4 ; Must be at least paragraph aligned
  1813. jb lms_ReadFromFile
  1814. cmp hBlock, 0
  1815. jne lms_ReadFromMemory
  1816. jmps lms_ReadFromFile
  1817. lms_next_segment:
  1818. add si,SIZE new_seg1
  1819. loop lms_ps_loop
  1820. lms_done:
  1821. retn
  1822. if ROM
  1823. lms_ReadFromRom:
  1824. push cx
  1825. push es
  1826. cCall FarLoadSegment,<es,di,0,-1>
  1827. jmps lms_DoneLoad
  1828. endif
  1829. lms_ReadFromFile:
  1830. push cx
  1831. push es
  1832. cCall FarLoadSegment,<es,di,fh,fh>
  1833. jmps lms_DoneLoad
  1834. lms_ReadFromMemory:
  1835. push cx
  1836. push es
  1837. cCall GlobalLock,<hBlock>
  1838. or dx, dx
  1839. jnz lms_still_here
  1840. cCall GlobalFree,<hBlock>
  1841. mov hBlock, 0
  1842. pop es
  1843. pop cx
  1844. jmps lms_ReadFromFile
  1845. lms_still_here:
  1846. ifdef WOW
  1847. cCall AllocSelectorWOW,<dx> ; same as allocselector. but the
  1848. mov RefSelector, dx ; new descriptor is not set.
  1849. else
  1850. cCall AllocSelector,<dx>
  1851. endif
  1852. pop es
  1853. mov bx, es:[si].ns_sector
  1854. xor dx, dx
  1855. mov cx, es:[ne_align]
  1856. push es
  1857. @@:
  1858. shl bx, 1
  1859. rcl dx, 1
  1860. loop @B
  1861. sub bx, off_FileOffset
  1862. sbb dx, seg_FileOffset
  1863. push ax
  1864. push es
  1865. ifdef WOW
  1866. ; same as longptradd. but the descriptor 'RefSelector' is used
  1867. ; to set the descriptor of 'ax'
  1868. cCall LongPtrAddWOW,<ax,cx,dx,bx, RefSelector, 1> ; (cx is 0)
  1869. else
  1870. cCall LongPtrAdd,<ax,cx,dx,bx> ; (cx is 0)
  1871. endif
  1872. pop es
  1873. dec cx
  1874. cCall FarLoadSegment,<es,di,dx,cx>
  1875. pop cx
  1876. push ax
  1877. cCall FreeSelector,<cx>
  1878. cCall GlobalUnlock,<hBlock>
  1879. pop ax
  1880. lms_DoneLoad:
  1881. pop es
  1882. pop cx
  1883. or ax,ax
  1884. jz lms_abort_load1
  1885. jmp lms_next_segment
  1886. lms_abort_load1:
  1887. jmp abort_load
  1888. ;-----------------------------------------------------------------------
  1889. ;
  1890. ; LMLetsGo -
  1891. ;
  1892. ;-----------------------------------------------------------------------
  1893. LMLetsGo:
  1894. push es
  1895. push Win_PDB ; Save current PDB
  1896. push topPDB ; Set it to Kernel's
  1897. pop Win_PDB
  1898. if ROM
  1899. ;
  1900. ; the cases are:
  1901. ;
  1902. ; 1 loading a ROM module:
  1903. ; selROMHdr <> 0, fLoadFromDisk == fReplaceModule == 0
  1904. ;
  1905. ; 2 loading a patch module:
  1906. ; selROMHdr, fLoadFromDisk <> 0, fReplaceModule == 0
  1907. ;
  1908. ; 3 loading an override module with same name:
  1909. ; selROMHdr <> 0, fReplaceModule <> 0, fLoadFromDisk == ?
  1910. ;
  1911. ; 4 loading an override module with a different name:
  1912. ; selROMHdr == fReplaceModule == 0
  1913. ;
  1914. ; 5 loading a module not in rom at all
  1915. ; selROMhdr == fReplaceModule == 0
  1916. ; is it case 4 or 5
  1917. mov ax, selROMHdr
  1918. or ax, fReplaceModule
  1919. jnz lg_no_rom_header
  1920. ; never replace a process
  1921. test es:[ne_flags],NENOTP
  1922. jz lg_file_load_res
  1923. push es
  1924. cCall <far ptr FindROMModule>, <es>
  1925. pop es
  1926. ; is it case 5
  1927. inc ax ; -1 = not found
  1928. jz lg_file_load_res
  1929. dec ax ; 0 = couldn't alloc selector
  1930. jnz lg_found_rom_same_name
  1931. ; ax == 0 => out of memory
  1932. mov ax, LME_MEM
  1933. retn
  1934. lg_found_rom_same_name:
  1935. mov selROMHdr, ax
  1936. mov fReplaceModule, ax
  1937. lg_no_rom_header:
  1938. ; is it case 3 or 4
  1939. cmp fReplaceModule, 0
  1940. jz @F
  1941. push es
  1942. cCall <near ptr ReplacePatchTable>, <es,selROMHdr>
  1943. pop es
  1944. or ax, ax
  1945. jmp lg_file_load_res
  1946. ; is it case 1 or 2?
  1947. sub cx, cx
  1948. @@: cmp fLoadFromDisk, 0
  1949. jz lg_resFromFile
  1950. ; loading a patch file; set the patch table selector, then
  1951. ; fall through to load resources
  1952. push ds
  1953. mov ds, selROMHdr
  1954. mov si, ds:[ne_cseg]
  1955. dec si
  1956. shl si, 3
  1957. add si, ds:[ne_segtab]
  1958. mov bx, ds:[si].ns_sector
  1959. pop ds
  1960. .errnz 2 + size new_seg - size new_seg1
  1961. ; also assumes both exehdrs have same ne_segtab!!!!
  1962. add si, es:[ne_cseg]
  1963. add si, es:[ne_cseg]
  1964. sub si, 2
  1965. mov ax, es:[si].ns_handle
  1966. Sel_To_Handle ax
  1967. cCall ChangeROMHandle, <ax,bx>
  1968. mov es:[si].ns_handle, bx
  1969. lg_file_load_res:
  1970. endif
  1971. mov ax, -1
  1972. cCall FarGetCachedFileHandle,<es,ax,ax>
  1973. if ROM
  1974. mov cx, selROMHdr
  1975. endif
  1976. cmp hBlock,0
  1977. je lg_resFromFile
  1978. if ROM
  1979. cCall PreloadResources,<es,ax,hBlock,FileOffset,0>
  1980. else
  1981. cCall PreloadResources,<es,ax,hBlock,FileOffset>
  1982. endif
  1983. jmps lg_gotRes
  1984. lg_resFromFile:
  1985. xor dx, dx
  1986. if ROM
  1987. cCall PreloadResources,<es,ax,dx,dx,dx,cx>
  1988. else
  1989. cCall PreloadResources,<es,ax,dx,dx,dx>
  1990. endif
  1991. lg_gotRes:
  1992. pop Win_PDB ; Restore PDB
  1993. pop es
  1994. mov ax,lpPBlock.off
  1995. mov dx,lpPBlock.sel
  1996. and ax,dx
  1997. inc ax
  1998. jnz lg_huh
  1999. mov lpPBlock.off,ax
  2000. mov lpPBlock.sel,ax
  2001. lg_huh: xor ax,ax ; free 0
  2002. push fLMdepth
  2003. mov fLMdepth, 0
  2004. push es
  2005. cCall StartModule,<ax,lpPBlock,es,fh>
  2006. pop es
  2007. mov hResult,ax
  2008. or ax,ax
  2009. jnz @F
  2010. jmp abort_load0
  2011. @@: test es:[ne_flags],NENOTP
  2012. jnz lg_not_a_process2
  2013. pop si
  2014. cCall CloseApplEnv,<hResult,pExe>
  2015. push bx
  2016. mov hResult,ax
  2017. mov hTDB,dx
  2018. lg_not_a_process2:
  2019. pop fLMdepth
  2020. retn
  2021. ;----------------------------------------------------------------------
  2022. ;
  2023. ; LMPrevInstance - internal routine for LoadModule
  2024. ; Load an app/dll if a previous instance in memory
  2025. ; Entry:
  2026. ; ax = handle of previous instance
  2027. ; Exit:
  2028. ; ax = status to return
  2029. ; dx = hTDB = TDB
  2030. ; Error:
  2031. ; ax < LME_MAXERR
  2032. ;
  2033. ;-----------------------------------------------------------------------
  2034. LMPrevInstance:
  2035. mov es,ax
  2036. mov dx,es:[ne_flags]
  2037. mov si,ax
  2038. mov pExe,ax ; why store in pExe and hExe?
  2039. mov hResult,0
  2040. if ROM
  2041. ; Error if multiple instance of ROM app with instance or auto data
  2042. ; (actually this might be okay if there are no entry points that need
  2043. ; to be patched--would require checks like in PatchCodeHandle).
  2044. test dh,(NENOTP SHR 8) ; okay if not a process
  2045. jnz @F
  2046. test dl,NEMODINROM ; module in rom?
  2047. jz @F
  2048. test dl,NEINST ; app have instance data?
  2049. jnz pi_mds
  2050. cmp es:[ne_autodata],0 ; how about an autodata segment?
  2051. jnz pi_mds ; can't patch the ROM code so can't
  2052. ; run the 2nd instance
  2053. @@:
  2054. endif
  2055. ; Error if dynamically linking to non-library module.
  2056. mov ax,lpPBlock.off
  2057. and ax,lpPBlock.sel
  2058. inc ax
  2059. jnz pi_app
  2060. test dx,NENOTP
  2061. jnz @F
  2062. mov ax, LME_LINKTASK ; can't dynalink to a task
  2063. retn
  2064. @@: mov lpPBlock.off,ax ; AX == 0
  2065. mov lpPBlock.sel,ax
  2066. pi_app:
  2067. test dx,NEINST
  2068. jnz @F
  2069. jmp pi_not_inst
  2070. @@: call LMCheckHeap
  2071. or ax, ax
  2072. jnz @F
  2073. mov ax, LME_MEM ; Out of (gdi/user) memory
  2074. retn
  2075. @@:
  2076. ifdef WOW
  2077. ;
  2078. ; if WOA invoked by app (not fWOA) fail it
  2079. ;
  2080. cmp fWOA,0 ; fWOA
  2081. jnz pi_not_multiple_data
  2082. cld
  2083. push si
  2084. push di
  2085. mov di, es:[ne_restab]
  2086. inc di
  2087. mov si, dataOffset WOAName
  2088. mov cx, 4
  2089. repe cmpsw
  2090. pop di
  2091. pop si
  2092. jnz @F
  2093. mov ax, LME_WOAWOW32
  2094. retn
  2095. @@:
  2096. endif
  2097. ; We refuse to load multiple instances of apps that have
  2098. ; multiple data segments. This is because we cannot do
  2099. ; fixups to these other data segments. What happens is
  2100. ; that the second copy of the app gets fixed up to the
  2101. ; data segments of the first application. For the case
  2102. ; of read-only data segments we make an exception since
  2103. ; what does it matter who the segments belong to?
  2104. mov ax, 2 ; if we have >= 2 dsegs we die
  2105. mov es,si
  2106. mov cx,es:[ne_cseg]
  2107. mov bx,es:[ne_segtab]
  2108. pi_next_seg:
  2109. test es:[bx].ns_flags,NSDATA ; scum! this barely works!
  2110. jz @F
  2111. test es:[bx].ns_flags,NSERONLY
  2112. jnz @F
  2113. dec ax
  2114. jnz @F ; two data segments is one too many!
  2115. pi_mds: mov ax, LME_APPMDS
  2116. retn
  2117. @@: add bx,SIZE NEW_SEG1
  2118. loop pi_next_seg
  2119. pi_not_multiple_data: ; Prepare the application
  2120. cCall OpenApplEnv,<lpPBlock,si,fWOA>
  2121. cCall GetInstance,<si> ; Why do we call this?
  2122. mov di,ax
  2123. cCall IncExeUsage,<si>
  2124. cCall AllocAllSegs,<si> ; Can we get memory?
  2125. inc ax
  2126. jnz @F
  2127. cCall DecExeUsage,<si> ; AllocAllSegs failed, Dec Usage
  2128. jmps pi_mem ; Must have failed from no memory
  2129. @@: mov ax,-1
  2130. cCall StartModule,<di,lpPBlock,si,ax>
  2131. ; mov hResult,ax
  2132. or ax,ax
  2133. jnz @F
  2134. mov es,si ; StartModule failed, FreeModule
  2135. mov si,es:[ne_pautodata]
  2136. cCall FreeModule,<es:[si].ns_handle>
  2137. pi_mem: mov ax, LME_MEM
  2138. retn
  2139. @@: mov si, fLMdepth
  2140. mov fLMdepth, 0
  2141. cCall CloseApplEnv,<ax,pExe>
  2142. mov fLMdepth, bx
  2143. mov hTDB,dx
  2144. retn
  2145. pi_not_inst:
  2146. mov ax,es:[ne_autodata] ; Make sure data segment is loaded.
  2147. or ax,ax
  2148. jz @F
  2149. or bx,-1
  2150. push es
  2151. cCall FarLoadSegment,<es,ax,bx,bx>
  2152. pop es
  2153. or ax,ax
  2154. jz pi_end ; yes, AX is already 0, but ...
  2155. @@:
  2156. push es ; for GetInstance
  2157. cCall IncExeUsage,<es>
  2158. cCall GetInstance ; ,<pExe>
  2159. pi_end:
  2160. retn
  2161. ;----------------------------------------------------------------------
  2162. ;
  2163. ; LMCleanUp - internal routine for LoadModule
  2164. ;
  2165. ;-----------------------------------------------------------------------
  2166. LMCleanUp:
  2167. ifdef WOW
  2168. cmp LMHadPEDLL,0
  2169. je @F
  2170. cmp ax, LME_MAXERR
  2171. jae @F
  2172. mov ax,LME_PE ; Reflect real error we tried to mask
  2173. KernelLogError <DBF_WARNING>,ERR_LOADMODULE,"Could not find Win16 copy of Win32 DLL, returning LME_PE."
  2174. @@:
  2175. endif
  2176. push ax ; save status for future
  2177. cmp ax, LME_MAXERR
  2178. jae @F
  2179. cCall my_lclose,<fh>
  2180. or fh, -1
  2181. ; Restore PDB if needed
  2182. @@: mov ax, -1
  2183. xchg SavePDB, ax
  2184. inc ax
  2185. jz @F
  2186. dec ax
  2187. mov Win_PDB, ax
  2188. ; Free FastLoad block if allocated
  2189. @@: cmp hBlock,0
  2190. je @F
  2191. cCall GlobalFree,<hBlock>
  2192. mov hBlock,0
  2193. if ROM
  2194. ; Free ROM selector if allocated
  2195. @@:
  2196. mov ax,selROMHdr ; FindROMExe allocates a selector
  2197. or ax,ax ; to the ROM Exe Header if found.
  2198. jz @F ; Free it here.
  2199. cCall far_free_temp_sel,<ax>
  2200. endif
  2201. ; Free app environment if failure and this was an app
  2202. @@:
  2203. pop ax
  2204. cmp ax,LME_MAXERR
  2205. jae @F
  2206. if KDEBUG
  2207. cmp ax, LME_INVEXE ; invalid format (WinOldAp)
  2208. jz cu_fred
  2209. cmp ax, LME_PE ; Win32 Portable Exe - try to load it
  2210. jz cu_fred
  2211. push ax
  2212. push bx
  2213. push es
  2214. les bx, lpModuleName
  2215. KernelLogError <DBF_WARNING>,ERR_LOADMODULE,"Error 0x#ax loading @ES:BX"
  2216. pop es
  2217. pop bx
  2218. pop ax
  2219. endif
  2220. cu_fred:
  2221. cmp loadTDB,0
  2222. je @F
  2223. mov bx,pExe
  2224. cmp bx,LME_MAXERR ; Did we load an ExeHeader?
  2225. jbe @F
  2226. mov es,bx
  2227. test es:[ne_flags],NENOTP
  2228. jnz @F
  2229. mov si, fLMdepth
  2230. mov fLMdepth, 0
  2231. cCall CloseApplEnv,<ax,es>
  2232. mov fLMdepth, bx
  2233. ; shouldn't cache file handles on removable devices cause it
  2234. ; makes share barf when the user swaps disks. this kills some
  2235. ; install apps. CraigC 8/8/91
  2236. @@:
  2237. push ax
  2238. cmp ax, LME_MAXERR ; real?
  2239. jbe @F
  2240. cmp OnHardDisk, 0 ; is it on a removable device?
  2241. jne @F
  2242. cCall GetExePtr, <ax> ; get module handle
  2243. cCall FlushCachedFileHandle, <ax> ; blow it off
  2244. ;** Log this entry only if in diagnostic mode
  2245. @@:
  2246. cmp fDiagMode,0 ; Only log if in diag mode
  2247. je LM_NoDiagExit
  2248. cmp fBooting,0 ; Only log if booting
  2249. je LM_NoDiagExit
  2250. pop ax ; Get the return code early
  2251. push ax
  2252. pusha ; Save all the registers
  2253. push ds
  2254. push es
  2255. ;** Write out the appropriate string
  2256. mov si,ax ; Save the return value
  2257. cmp ax,LME_MAXERR
  2258. jae LM_DiagSuccess
  2259. mov ax,dataOFFSET szLoadFail ; Write the string
  2260. jmp SHORT LM_DiagOutput
  2261. LM_DiagSuccess:
  2262. mov ax,dataOFFSET szLoadSuccess ; Write the string
  2263. LM_DiagOutput:
  2264. cCall DiagOutput, <ds,ax>
  2265. cCall DiagOutput, <lpModuleName>
  2266. cmp si,LME_MAXERR ; Don't do this on success
  2267. jae SHORT LM_DiagSuccessSkip
  2268. ;** Log a message complete with the failure code
  2269. mov ax,si ; Get the failure code
  2270. shr al, 4
  2271. mov bx,dataOFFSET szCodeString ; Point to the second digit
  2272. push NREScodeOffset afterHex
  2273. call toHex
  2274. mov ax, si
  2275. inc bx
  2276. toHex:
  2277. and al,0fh ; Get low hex digit
  2278. add al,'0' ; Convert to ASCII
  2279. cmp al,'9' ; Letter?
  2280. jbe @F ; Yes
  2281. add al,'A' - '0' ; Make it a letter
  2282. @@: mov [bx],al ; Save the digit
  2283. retn
  2284. afterHex:
  2285. mov ax,dataOFFSET szFailCode ; Get the string 'Failure code is '
  2286. cCall DiagOutput, <ds,ax>
  2287. LM_DiagSuccessSkip:
  2288. mov ax,dataOFFSET szCRLF
  2289. cCall DiagOutput, <ds,ax>
  2290. pop es
  2291. pop ds
  2292. popa
  2293. LM_NoDiagExit:
  2294. pop ax
  2295. dec fLMdepth
  2296. mov dx,hTDB
  2297. retn
  2298. ;@@end
  2299. ;shl_ax16: ; shift AX into DX:AX by cl bits
  2300. ; mov dx, ax
  2301. ; shl ax, cl
  2302. ; neg cl
  2303. ; add cl, 16 ; cl = 16 - cl
  2304. ; shr dx, cl
  2305. ; retn
  2306. LoadModuleEnd: ; jmp here to clean up stack and RET
  2307. ifdef WOW
  2308. cmp ax, LME_MAXERR
  2309. jb @F
  2310. lmntex:
  2311. jmp LoadModuleExit
  2312. @@:
  2313. ;
  2314. ; Exec For Non 16 Bit Windows Apps
  2315. ;
  2316. ;
  2317. ; WIN 32S App ? yes -> let NT load it
  2318. ;
  2319. cmp ax,LME_PE
  2320. je LM_NTLoadModule
  2321. ;
  2322. ; if an app is spawning WOA (NOT our internal load-fWOA),
  2323. ; Patch lpModuleName to -1 let NT load it
  2324. ;
  2325. cmp ax,LME_WOAWOW32
  2326. jne @F
  2327. mov word ptr lpModuleName[2], -1 ; patch lpModuleName
  2328. mov word ptr lpModuleName[0], -1
  2329. jmp short LM_NTLoadModule
  2330. @@:
  2331. ; Errors 11-15 -> let NT load it
  2332. cmp ax,LME_RMODE
  2333. jae lmntex
  2334. cmp ax,LME_VERS
  2335. jbe lmntex
  2336. public LM_NTLoadModule
  2337. LM_NTLoadModule:
  2338. ;
  2339. ; WOW Execs non-windows apps using WINOLDAP.
  2340. ;
  2341. ; First check for loading of a 32bit DLL. lpPBlock will be -1
  2342. ; in such a case.
  2343. push ax
  2344. mov ax,lpPBlock.off
  2345. and ax,lpPBlock.sel
  2346. inc ax
  2347. pop ax
  2348. jz LoadModuleExit
  2349. ;
  2350. ; This is an EXE, but the LME_PE failure code might have come from
  2351. ; an implicitly linked DLL. If so, we don't want to try having
  2352. ; Win32 lauch the win16 EXE, as it will just come back to us.
  2353. ;
  2354. cmp ax,LME_PE
  2355. jne @F
  2356. cmp ax,hDepFail
  2357. je short LoadModuleExit
  2358. @@:
  2359. sub sp, 80 ; alloc space for cmdline
  2360. mov di, sp
  2361. smov es, ss
  2362. mov word ptr es:[di], 0 ; set WindOldApp CmdLine to NULL
  2363. regptr esdi,es,di
  2364. cCall WowLoadModule,<lpModuleName, lpPBlock, esdi>
  2365. ;
  2366. ; if ax < 33 an error occurred
  2367. ;
  2368. cmp ax, 33
  2369. jb ex8
  2370. or Kernel_flags[1],KF1_WINOLDAP
  2371. mov ax, ss
  2372. les si,lpPBlock
  2373. mov es:[si].lpcmdline.off,di
  2374. mov es:[si].lpcmdline.sel,ax
  2375. mov si,dataOffset WOAName
  2376. regptr dssi,ds,si
  2377. cCall LoadModule,<dssi, lpPBlock>
  2378. cmp ax,32 ; check for error...
  2379. jae ex8
  2380. ;
  2381. ; LoadModule of WinOldApp failed
  2382. ; Call WowLoadModule to clean up process handle
  2383. ;
  2384. push ax
  2385. mov ax, ss
  2386. regptr axdi,ax,di
  2387. cCall WowLoadModule,<0, lpPBlock, axdi>
  2388. pop ax
  2389. cmp ax,2 ; file not found?
  2390. jnz ex7 ; no, return error
  2391. mov al, LME_WOAWOW32 ; flag WINOLDAP error
  2392. ex7:
  2393. or ax,ax ; out of memory?
  2394. jnz ex8
  2395. mov ax,8h ; yes, return proper error code
  2396. ex8:
  2397. add sp,80 ; free space for cmdline
  2398. endif; WOW
  2399. LoadModuleExit:
  2400. cEnd
  2401. ?DOS5 = ?SAV5
  2402. ;-----------------------------------------------------------------------;
  2403. ; My_lclose
  2404. ;
  2405. ; Close file handle if it isn't -1.
  2406. ;
  2407. ; Entry:
  2408. ;
  2409. ; Returns:
  2410. ;
  2411. ; Registers Destroyed:
  2412. ;
  2413. ; History:
  2414. ;
  2415. ;-----------------------------------------------------------------------;
  2416. assumes ds,nothing
  2417. assumes es,nothing
  2418. cProc My_lclose,<PUBLIC,NEAR>
  2419. parmW fh
  2420. cBegin
  2421. mov ax,fh
  2422. inc ax
  2423. jz mlc_exit
  2424. cCall _lclose,<fh>
  2425. mlc_exit:
  2426. cEnd
  2427. if ROM
  2428. ;-----------------------------------------------------------------------;
  2429. ; FindROMExe
  2430. ;
  2431. ; Locates the ROM EXE header for a module in ROM.
  2432. ;
  2433. ; Entry:
  2434. ;
  2435. ; Returns:
  2436. ;
  2437. ; Registers Destroyed:
  2438. ;
  2439. ; History:
  2440. ;
  2441. ;-----------------------------------------------------------------------;
  2442. assumes ds,nothing
  2443. assumes es,nothing
  2444. cProc FindROMExe,<PUBLIC,FAR>,<ds,es,di,si>
  2445. parmD lpFileName
  2446. cBegin
  2447. xor ax,ax ; calculate length of
  2448. mov cx,-1 ; file name, include
  2449. les di,lpFileName ; terminating null in count
  2450. cld
  2451. repne scasb
  2452. not cx
  2453. jcxz fre_exit
  2454. cmp cx,File_Name_Len ; can't be in rom if name
  2455. ja fre_exit ; is too long
  2456. call MapDStoDATA
  2457. ReSetKernelDS
  2458. mov ds,selROMTOC ; search ROM TOC for matching
  2459. UnSetKernelDS ; module name
  2460. mov bx,ds:[cModules] ; # modules in ROM TOC
  2461. mov ax,ModEntries+FileNameStr ; offset in ROM TOC of 1st name
  2462. les di,lpFileName
  2463. mov dx,cx
  2464. fre_next:
  2465. mov si,ax ; search ROM TOC, entry by entry
  2466. push ax
  2467. next_chr:
  2468. mov al, es:[di]
  2469. call FarMyUpper ; case insensitive
  2470. cmp al, ds:[si]
  2471. jne @f
  2472. inc si
  2473. inc di
  2474. loop next_chr
  2475. pop ax
  2476. jmps fre_got_it
  2477. @@:
  2478. pop ax
  2479. dec bx
  2480. jz fre_failed
  2481. mov cx,dx
  2482. add ax,size MODENT
  2483. mov di,lpFileName.off
  2484. jmps fre_next
  2485. fre_failed:
  2486. xor ax,ax ; no matching module, return 0
  2487. jmps fre_exit
  2488. fre_got_it:
  2489. mov si,ax ; return selector pointing
  2490. sub si,FileNameStr
  2491. mov ax,word ptr [si.lmaExeHdr] ; to ROM copy of module
  2492. mov dx,word ptr [si.lmaExeHdr+2] ; EXE header
  2493. cCall far_alloc_data_sel16,<dx,ax,1000h>
  2494. if PMODE32
  2495. cCall HocusROMBase, <ax>
  2496. endif
  2497. fre_exit:
  2498. cEnd
  2499. endif ;ROM
  2500. if ROM
  2501. ;-----------------------------------------------------------------------;
  2502. ; FindROMFile
  2503. ;
  2504. ; Locates the start of a file in ROM ( for true-type files esp.)
  2505. ;
  2506. ; Entry:
  2507. ;
  2508. ; Returns:
  2509. ;
  2510. ; Registers Destroyed:
  2511. ;
  2512. ; History:
  2513. ; adapted from FindROMExe -- 8/8/91 -- vatsanp
  2514. ;
  2515. ;-----------------------------------------------------------------------;
  2516. assumes ds,nothing
  2517. assumes es,nothing
  2518. cProc FindROMFile,<PUBLIC,FAR>,<ds,es,di,si>
  2519. parmD lpFileName
  2520. parmD lpfsize
  2521. cBegin
  2522. xor ax,ax ; calculate length of
  2523. mov cx,-1 ; file name, include
  2524. les di,lpFileName ; terminating null in count
  2525. cld
  2526. repne scasb
  2527. not cx
  2528. jcxz frf_failed ; to frf_exit
  2529. cmp cx,File_Name_Len ; can't be in rom if name
  2530. ja frf_exit ; is too long
  2531. call MapDStoDATA
  2532. ReSetKernelDS
  2533. mov ds,selROMTOC ; search ROM TOC for matching
  2534. UnSetKernelDS ; file name
  2535. mov bx,ds:[cModules] ; # modules in ROM TOC
  2536. mov ax, SIZE MODENT
  2537. mul bx
  2538. mov bx,ModEntries+fname ; offset in ROM TOC of 1st name
  2539. add ax, bx
  2540. mov bx,ds:[cFiles] ; # Files in ROM TOC
  2541. les di,lpFileName
  2542. mov dx,cx
  2543. frf_next:
  2544. mov si,ax ; search ROM TOC, entry by entry
  2545. cld
  2546. repe cmpsb
  2547. je frf_got_it
  2548. dec bx
  2549. jz frf_failed
  2550. mov cx,dx
  2551. add ax,size FILENT
  2552. mov di,lpFileName.off
  2553. jmps frf_next
  2554. frf_failed:
  2555. xor ax,ax ; no matching module, return 0
  2556. jmps frf_exit
  2557. frf_got_it:
  2558. mov si,ax ; return selector pointing
  2559. sub si,fname
  2560. les di,lpfsize
  2561. mov cx, word ptr [si.fsize] ; massage fsize into paras
  2562. mov word ptr es:[di], cx
  2563. mov ax, word ptr [si.fsize+2]
  2564. mov word ptr es:[di+2], ax
  2565. shl ax, 12
  2566. add cx, 15 ; round off
  2567. shr cx, 4
  2568. or cx, ax
  2569. mov ax,word ptr [si.lma] ; to ROM copy of file
  2570. mov dx,word ptr [si.lma+2]
  2571. cCall far_alloc_data_sel16,<dx,ax,cx>
  2572. if PMODE32
  2573. add cx, 0FFFh ; compute #sels allocated
  2574. rcr cx, 1
  2575. shr cx, 11 ; cx = # of sels allocated
  2576. mov dx, ax ; save
  2577. anudder_sel:
  2578. cCall HocusROMBase, <ax> ; for each of those sels
  2579. add ax, 8 ; next sel
  2580. loop anudder_sel
  2581. mov ax, dx ; restore
  2582. endif
  2583. frf_exit:
  2584. cEnd
  2585. endif ;ROM
  2586. ;-----------------------------------------------------------------------;
  2587. ; WarnRealMode
  2588. ;
  2589. ; Trayf for files in the form "Insert WIN.EXE disk in drive A:"
  2590. ;
  2591. ; Entry:
  2592. ;
  2593. ; Returns:
  2594. ;
  2595. ; Registers Destroyed:
  2596. ;
  2597. ; History:
  2598. ; Sat 07-Oct-1989 17:12:43 -by- David N. Weise [davidw]
  2599. ; Wrote it! A month or so ago.
  2600. ;-----------------------------------------------------------------------;
  2601. assumes ds,nothing
  2602. assumes es,nothing
  2603. cProc WarnRealMode,<PUBLIC,NEAR>
  2604. cBegin nogen
  2605. ReSetKernelDS
  2606. push Win_PDB
  2607. push fLMDepth
  2608. cld
  2609. mov ax,IDCANCEL ; assume booting
  2610. test fBooting,1
  2611. jnz promptly_done
  2612. cmp pMBoxProc.sel,0 ; is there a USER around yet?
  2613. jz promptly_done
  2614. push di
  2615. push si
  2616. push es
  2617. mov es,cx
  2618. ifdef FE_SB
  2619. ;Japan and Korea declare that they need more space for DBCS msg.
  2620. ;It sounds like this is one of common requirement for DBCS enabling
  2621. ;although Taiwan doesn't claim she has the same requirement.
  2622. ;I enclosed this code fragment under DBCS and it can be removed
  2623. ;if somebody thinks it is not necessary.
  2624. sub sp, 530
  2625. else
  2626. sub sp,512
  2627. endif
  2628. mov di,sp
  2629. mov si,offset msgRealModeApp1
  2630. push ds
  2631. smov ds,cs
  2632. UnSetKernelDS
  2633. call StartString
  2634. smov ds,cs
  2635. mov si,offset msgRealModeApp2
  2636. call Append
  2637. pop ds
  2638. ReSetKernelDS
  2639. mov bx,sp
  2640. xor ax,ax
  2641. push ax ; Null hwnd
  2642. push ss
  2643. push bx ; (lpstr)text
  2644. push cs
  2645. mov ax,offset szProtectCap
  2646. push ax ; (lpstr)caption
  2647. mov ax,MB_OKCANCEL or MB_ICONEXCLAMATION or MB_DEFBUTTON2 or MB_SYSTEMMODAL
  2648. push ax ; wType
  2649. call [pMBoxProc] ; Call USER.MessageBox
  2650. ifdef FE_SB
  2651. add sp, 530
  2652. else
  2653. add sp,512
  2654. endif
  2655. pop es
  2656. pop si
  2657. pop di
  2658. promptly_done:
  2659. pop fLMDepth
  2660. pop Win_PDB
  2661. ret
  2662. cEnd nogen
  2663. assumes ds,nothing
  2664. assumes es,nothing
  2665. StartString:
  2666. call Append ; append first string
  2667. ; Now append the file name
  2668. push di
  2669. lea di,[bx].opFile ; skip past length, date, time
  2670. call NResGetPureName ; strip off drive and directory
  2671. smov ds,es
  2672. mov si,di
  2673. pop di
  2674. ; Append ASCIIZ string to output buffer, DS:DX points to string
  2675. assumes ds,nothing
  2676. assumes es,nothing
  2677. Append: lodsb
  2678. stosb
  2679. or al,al
  2680. jnz Append
  2681. dec di
  2682. ret
  2683. assumes ds,nothing
  2684. assumes es,nothing
  2685. ;-----------------------------------------------------------------------;
  2686. ; NResGetPureName
  2687. ;
  2688. ; Returns a pointer the the filename off the end of a path
  2689. ;
  2690. ; Entry:
  2691. ; ES:DI => path\filename
  2692. ; Returns:
  2693. ; ES:DI => filename
  2694. ; Registers Destroyed:
  2695. ;
  2696. ; History:
  2697. ; Wed 18-Oct-1989 20:01:25 -by- David N. Weise [davidw]
  2698. ;
  2699. ;-----------------------------------------------------------------------;
  2700. assumes ds,nothing
  2701. assumes es,nothing
  2702. cProc NResGetPureName,<PUBLIC,NEAR>
  2703. cBegin nogen
  2704. ifdef FE_SB
  2705. ;
  2706. ; It is not possible to search filename delimiter by backword search
  2707. ; in case of DBCS version. so we use forword search instead.
  2708. ;
  2709. mov bx,di
  2710. iup0:
  2711. mov al,es:[di]
  2712. test al,al ; end of string?
  2713. jz iup2 ; jump if so
  2714. inc di
  2715. cmp al,'\'
  2716. jz iup1
  2717. cmp al,'/'
  2718. jz iup1
  2719. cmp al,':'
  2720. jz iup1
  2721. call FarMyIsDBCSLeadByte ; see if char is DBC
  2722. jc iup0 ; jump if not a DBC
  2723. inc di ; skip to detemine 2nd byte of DBC
  2724. jmp iup0
  2725. iup1:
  2726. mov bx,di ; update purename candidate
  2727. jmp iup0
  2728. iup2:
  2729. mov di,bx ; di points purename pointer
  2730. ret
  2731. else
  2732. cld
  2733. xor al,al
  2734. mov cx,-1
  2735. mov bx,di
  2736. repne scasb
  2737. inc cx
  2738. inc cx
  2739. neg cx
  2740. iup0: cmp bx,di ; back to beginning of string?
  2741. jz iup1 ; yes, di points to name
  2742. mov al,es:[di-1] ; get next char
  2743. cmp al,'\' ; next char a '\'?
  2744. jz iup1 ; yes, di points to name
  2745. cmp al,'/' ; next char a '/'
  2746. jz iup1
  2747. cmp al,':' ; next char a ':'
  2748. jz iup1 ; yes, di points to name
  2749. dec di ; back up one
  2750. jmp iup0
  2751. iup1: ret
  2752. endif
  2753. cEnd nogen
  2754. ;-----------------------------------------------------------------------;
  2755. ; search_mod_dep_list
  2756. ;
  2757. ; Searches the dependent module list for the passed in name.
  2758. ;
  2759. ; Entry:
  2760. ; AX = length of name to search for
  2761. ; CX = count of modules
  2762. ; DS:SI => module name to search for
  2763. ; ES:DI => module table
  2764. ; Returns:
  2765. ;
  2766. ; Registers Preserved:
  2767. ; AX,BX,CX,DI,SI,ES
  2768. ;
  2769. ; Registers Destroyed:
  2770. ;
  2771. ; History:
  2772. ; Sat 07-Oct-1989 17:12:43 -by- David N. Weise [davidw]
  2773. ;
  2774. ;-----------------------------------------------------------------------;
  2775. assumes ds,nothing
  2776. assumes es,nothing
  2777. cProc search_mod_dep_list,<PUBLIC,NEAR>
  2778. cBegin nogen
  2779. push bx
  2780. push cx
  2781. push di
  2782. mov bx,di
  2783. search_mod_loop:
  2784. mov di,es:[bx] ; es:di = offset into imptable
  2785. add di,es:[ne_imptab]
  2786. cmp es:[di],al ; does len of entry = sizeof(doscalls)
  2787. jnz get_next_entry
  2788. push cx ; cx holds count of module entries.
  2789. push si
  2790. inc di ; es:di = import module name
  2791. mov cx,ax
  2792. rep cmpsb
  2793. pop si
  2794. pop cx
  2795. stc
  2796. jz got_it
  2797. get_next_entry:
  2798. inc bx
  2799. inc bx
  2800. loop search_mod_loop
  2801. clc
  2802. got_it: pop di
  2803. pop cx
  2804. pop bx
  2805. ret
  2806. cEnd nogen
  2807. ;-----------------------------------------------------------------------;
  2808. ; LMCheckHeap
  2809. ;
  2810. ; This checks for 4K free space in both USER's and GDI's data
  2811. ; segments. If this space does not exist then we will not load
  2812. ; the app. This is better than the hose-bag way we did things
  2813. ; under win 1 and 2.
  2814. ;
  2815. ; Entry:
  2816. ; nothing
  2817. ;
  2818. ; Returns:
  2819. ; AX != 0 lots o'space
  2820. ;
  2821. ; Registers Destroyed:
  2822. ; BX,CX
  2823. ;
  2824. ; History:
  2825. ; Sat 28-Oct-1989 17:49:09 -by- David N. Weise [davidw]
  2826. ; Wrote it!
  2827. ;-----------------------------------------------------------------------;
  2828. assumes ds,nothing
  2829. assumes es,nothing
  2830. MIN_RSC = 10
  2831. cProc LMCheckHeap,<PUBLIC,NEAR>,<ds>
  2832. cBegin
  2833. SetKernelDSNRES
  2834. ifdef WOW
  2835. ; USER32 and GDI32 can deal with memory alloc no need check heaps on WOW
  2836. mov ax,-1 ; WOW doesn't have GDI or User heaps
  2837. else ; so don't check them.
  2838. mov ax, MIN_RSC
  2839. cmp word ptr pGetFreeSystemResources[2],0
  2840. jz @F
  2841. cCall pGetFreeSystemResources,<0>
  2842. cmp ax, MIN_RSC
  2843. jae @F
  2844. if kdebug ; test low memory code if DEBUG
  2845. krDebugOut DEB_WARN, "Resources #ax% - this tests your error handling code"
  2846. or al, 1
  2847. else
  2848. xor ax, ax ; you failed - g'bye
  2849. endif
  2850. @@:
  2851. endif ; WOW
  2852. ReSetKernelDS
  2853. cEnd
  2854. if 0
  2855. cProc check_gdi_user_heap_space,<PUBLIC,NEAR>
  2856. cBegin nogen
  2857. ReSetKernelDS
  2858. ifdef WOW
  2859. ; USER32 and GDI32 can deal with memory alloc no need check heaps on WOW
  2860. mov ax,-1 ; WOW doesn't have GDI or User heaps
  2861. else ; so don't check them.
  2862. cmp graphics,0
  2863. jz c_ret
  2864. push dx
  2865. push es
  2866. push ds
  2867. mov ds,hGDI
  2868. UnSetKernelDS
  2869. call checkit_bvakasha
  2870. or ax,ax
  2871. jz c_exit
  2872. pop ds
  2873. ReSetKernelDS
  2874. push ds
  2875. mov ds,hUser
  2876. UnSetKernelDS
  2877. call checkit_bvakasha
  2878. c_exit: pop ds
  2879. pop es
  2880. pop dx
  2881. c_ret: ret
  2882. public checkit_bvakasha
  2883. checkit_bvakasha:
  2884. mov bx,ds:[ne_pautodata]
  2885. cCall FarMyLock,<ds:[bx].ns_handle>
  2886. mov ds,ax
  2887. call LocalCountFree
  2888. sub ax,4095
  2889. ja cguhs_exit
  2890. neg ax
  2891. mov bx,LA_MOVEABLE
  2892. cCall LocalAlloc,<bx,ax>
  2893. or ax,ax
  2894. jz cguhs_exit
  2895. free_User_piece:
  2896. cCall LocalFree,<ax>
  2897. mov ax,sp ; return non-zero
  2898. cguhs_exit:
  2899. endif ;WOW
  2900. ret
  2901. cEnd nogen
  2902. endif
  2903. ;-----------------------------------------------------------------------;
  2904. ; GetHeapSpaces
  2905. ;
  2906. ;
  2907. ; Entry:
  2908. ; nothing
  2909. ;
  2910. ; Returns:
  2911. ; AX = free space (bytes) of User heap assuming heap can grow to 64K
  2912. ; DX = free space (bytes) of GDI heap assuming heap can grow to 64K
  2913. ; Registers Destroyed:
  2914. ;
  2915. ; History:
  2916. ; Wed 10-Jan-1990 22:27:38 -by- David N. Weise [davidw]
  2917. ; Wrote it!
  2918. ;-----------------------------------------------------------------------;
  2919. assumes ds,nothing
  2920. assumes es,nothing
  2921. cProc GetHeapSpaces,<PUBLIC,FAR>,<di,si>
  2922. parmW hInstance
  2923. cBegin
  2924. call MapDStoDATA
  2925. ReSetKernelDS
  2926. cCall FarMyLock,<hInstance>
  2927. or ax,ax
  2928. jz ghs_exit
  2929. mov ds,ax
  2930. cmp ds:[ne_magic],NEMAGIC
  2931. jnz ghs_must_be_data
  2932. mov bx,ds:[ne_pautodata]
  2933. cCall FarMyLock,<ds:[bx].ns_handle>
  2934. mov ds,ax
  2935. ghs_must_be_data:
  2936. call LocalCountFree
  2937. mov si,ax
  2938. cCall GlobalSize,<ds>
  2939. neg ax
  2940. add ax,si ; AX = size of free assuming 64K
  2941. mov cx,si ; CX = size of free
  2942. mov dx,-1
  2943. sub dx,ds:[pLocalHeap] ; DX = size of heap
  2944. ghs_exit:
  2945. cEnd
  2946. if ROM
  2947. ;-----------------------------------------------------------------------;
  2948. ; FindROMModule
  2949. ;
  2950. ; search through the the exehdr's listed in the ROM TOC for a specific
  2951. ; module name
  2952. ;
  2953. ; Entry:
  2954. ; Returns:
  2955. ; Registers Destroyed:
  2956. ;
  2957. ; History:
  2958. ; Wed 01-May-1991 13:11:38 -by- Craig A. Critchley [craigc]
  2959. ; Wrote it!
  2960. ;-----------------------------------------------------------------------;
  2961. cProc FindROMModule, <PUBLIC,FAR>, <si, di>
  2962. parmW hExe
  2963. cBegin
  2964. push ds
  2965. call MapDSToData
  2966. ResetKernelDS
  2967. mov es, selROMTOC
  2968. mov ds, hExe
  2969. UnsetKernelDS
  2970. mov cx, es:[cModules] ; get number of modules
  2971. lea bx, es:[ModEntries] ; point to first module
  2972. frm_loop:
  2973. push cx ; save count
  2974. lea di, [bx].ModNameStr ; point to module name string
  2975. mov si, ds:[ne_restab] ; point to res name table
  2976. sub cx, cx
  2977. lodsb ; get count in name table
  2978. mov cl, al
  2979. repe cmpsb ; compare up to that length
  2980. jnz frm_pass ; if mismatch, next
  2981. cmp es:[di], cl ; make sure there's a zero term
  2982. jnz frm_pass
  2983. pop cx
  2984. mov ax, word ptr es:lmaExeHdr[bx][0]
  2985. mov dx, word ptr es:lmaExeHdr[bx][2]
  2986. cCall far_alloc_data_sel16, <dx,ax,1000h>
  2987. if PMODE32
  2988. cCall HocusROMBase, <ax>
  2989. endif
  2990. jmp short frm_ret
  2991. frm_pass:
  2992. add bx, size MODENT
  2993. pop cx
  2994. loop frm_loop
  2995. mov ax, -1
  2996. frm_ret:
  2997. pop ds
  2998. cEnd
  2999. ;-----------------------------------------------------------------------;
  3000. ; ReplacePatchTable
  3001. ;
  3002. ; this function generates a new patch table when a module is loaded
  3003. ; from disk to replace the one in RAM.
  3004. ;
  3005. ; we do this by walking the entry table in the rom module, finding all
  3006. ; exported entry points, finding the corresponding entry point in the
  3007. ; new exe, and placing a far jump at that offset in the new segment.
  3008. ;
  3009. ; Entry:
  3010. ; Returns:
  3011. ; Registers Destroyed:
  3012. ;
  3013. ; History:
  3014. ; Wed 01-May-1991 13:11:38 -by- Craig A. Critchley [craigc]
  3015. ; Wrote it!
  3016. ;-----------------------------------------------------------------------;
  3017. OP_FARJUMP equ 0EAh
  3018. public enter_patch
  3019. enter_patch proc near
  3020. push ax
  3021. push bx
  3022. push cx
  3023. push dx
  3024. push es
  3025. cCall GetProcAddress,<dx,0,cx>
  3026. pop es
  3027. or dx, dx
  3028. jz @F
  3029. mov es:[di+1],ax
  3030. mov es:[di+3],dx
  3031. @@: pop dx
  3032. pop cx
  3033. pop bx
  3034. pop ax
  3035. ret
  3036. enter_patch endp
  3037. cProc ReplacePatchTable, <PUBLIC>, <si, di>
  3038. parmW hExe
  3039. parmW selROMHdr
  3040. localW hCodeSeg
  3041. cBegin
  3042. sub ax, ax
  3043. mov es, selROMHdr
  3044. test es:[ne_flagsothers], NEGANGLOAD
  3045. jnz rpt_ok ; one of these bits is set
  3046. ifdef PATCHCHECK
  3047. test byte ptr es:[ne_gang_start+1], 4
  3048. jz rpt_ok
  3049. endif
  3050. mov ax, es:[ne_cseg]
  3051. cmp al, byte ptr es:[ne_gang_start]
  3052. jz rpt_has_table
  3053. ifdef PATCHCHECK
  3054. sub ax, ax
  3055. jmp short rpt_not_ok
  3056. endif
  3057. rpt_ok:
  3058. mov ax, 1 ; doesn't have patch table
  3059. rpt_not_ok:
  3060. jmp rpt_exit
  3061. rpt_has_table: ; allocate memory for the
  3062. mov si, es:[ne_cseg] ; segment
  3063. dec si
  3064. shl si, 3
  3065. .errnz size new_seg - 8
  3066. add si, es:[ne_segtab]
  3067. mov ax, es:[si].ns_minalloc
  3068. xor dx, dx
  3069. push ax
  3070. cCall GlobalAlloc, <GA_MOVEABLE,dx,ax>
  3071. pop si
  3072. or ax, ax
  3073. jnz @F
  3074. jmp rpt_exit
  3075. @@: cCall GlobalLock, <ax> ; lock it
  3076. mov hCodeSeg, dx
  3077. mov es, dx
  3078. sub di, di ; initialize it to JMP UNDEFDYNLINK
  3079. cld
  3080. sub si, 4 ; don't overrun segment
  3081. rpt_initloop:
  3082. mov al, OP_FARJUMP
  3083. stosb
  3084. mov ax, offset UndefDynLink
  3085. stosw
  3086. mov ax, seg UndefDynLink
  3087. stosw
  3088. cmp di, si
  3089. jb rpt_initloop
  3090. push ds ; set up for entry table
  3091. mov ds, selROMHdr
  3092. mov si, ds:[ne_enttab]
  3093. mov bx, ds:[ne_cseg]
  3094. mov cx, 1 ; first export = 1
  3095. mov dx, hExe
  3096. rpt_ent_loop:
  3097. lodsw ; get count and segment
  3098. or al, al
  3099. jz rpt_ent_done ; if count 0, done
  3100. inc ah ; is seg == 0xFF
  3101. jnz rpt_not_moveable_entries
  3102. rpt_mov_ent_loop:
  3103. test byte ptr [si], ENT_PUBLIC
  3104. jz rpt_mov_ent_loop_pass
  3105. cmp bl, 3[si]
  3106. jnz rpt_mov_ent_loop_pass ; must be patch segment
  3107. mov di, 4[si]
  3108. call enter_patch
  3109. rpt_mov_ent_loop_pass:
  3110. inc cx
  3111. add si, 6
  3112. dec al
  3113. jnz rpt_mov_ent_loop
  3114. jmp rpt_ent_loop
  3115. rpt_not_moveable_entries:
  3116. dec ah ; is seg == 0
  3117. jnz rpt_fixed_entries
  3118. add cx, ax ; seg=0 = unused entries
  3119. jmp short rpt_ent_loop
  3120. rpt_fixed_entries:
  3121. cmp bl, ah ; must be in patch segment
  3122. jz rpt_fixed_ent_loop
  3123. sub ah, ah
  3124. add cx, ax ; update the ordinal count
  3125. add si, ax
  3126. add si, ax ; skip over entries in table
  3127. add si, ax
  3128. jmp rpt_ent_loop
  3129. rpt_fixed_ent_loop:
  3130. test byte ptr [si], ENT_PUBLIC
  3131. jz rpt_fixed_loop_pass
  3132. mov di, 1[si]
  3133. call enter_patch
  3134. rpt_fixed_loop_pass:
  3135. inc cx
  3136. add si, 3
  3137. dec al
  3138. jnz rpt_fixed_ent_loop
  3139. jmp rpt_ent_loop
  3140. rpt_ent_done:
  3141. pop ds
  3142. cCall IPrestoChangoSelector, <hCodeSeg,hCodeSeg>
  3143. mov es, selROMHdr
  3144. mov bx, es:[ne_cseg]
  3145. dec bx
  3146. shl bx, 3
  3147. add bx, es:[ne_segtab]
  3148. cCall ChangeROMHandle, <hCodeSeg,es:[bx].ns_sector>
  3149. rpt_exit:
  3150. cEnd
  3151. endif
  3152. ;-----------------------------------------------------------------------;
  3153. ; IsROMModule
  3154. ;
  3155. ; Determines if an app with a given name is a ROM application
  3156. ;
  3157. ; Entry:
  3158. ; Returns:
  3159. ; Registers Destroyed:
  3160. ;
  3161. ; History:
  3162. ; Wed 01-May-1991 13:11:38 -by- Craig A. Critchley [craigc]
  3163. ; Wrote it!
  3164. ;-----------------------------------------------------------------------;
  3165. if ROM
  3166. cProc IsROMModule, <FAR, PUBLIC>, <si, di>
  3167. parmD lpModule
  3168. parmW fSelector
  3169. localV szName, 18
  3170. cBegin
  3171. cld
  3172. mov cx, 13
  3173. push ds
  3174. push ss
  3175. pop es
  3176. lea di, szName
  3177. assumes ds,nothing
  3178. lds si, lpModule
  3179. skip_space: ; skip leading spaces
  3180. cmp byte ptr [si], ' '
  3181. jnz find_it
  3182. inc si
  3183. jmp short skip_space
  3184. path_char:
  3185. pop ds
  3186. xor ax, ax
  3187. jmp short IRM_Exit
  3188. find_it: ; if : / or \, not in ROM
  3189. lodsb
  3190. cmp al, ':'
  3191. jz path_char
  3192. cmp al, '\'
  3193. jz path_char
  3194. cmp al, '/'
  3195. jz path_char
  3196. cmp al, ' ' ; if illegal character, end of path
  3197. jbe end_char
  3198. cmp al, '<'
  3199. jz end_char
  3200. cmp al, '>'
  3201. jz end_char
  3202. cmp al, '|'
  3203. jz end_char
  3204. stosb ; store up to 13 chars
  3205. loop find_it
  3206. end_char:
  3207. mov byte ptr es:[di], 0 ; 0 terminate...
  3208. pop ds ; get DS back
  3209. lea ax, szName ; find exe header in ROMTOC
  3210. cCall FindROMExe, <ss, ax>
  3211. or ax, ax
  3212. jz IRM_Exit
  3213. IRM_Found:
  3214. cmp fSelector,0
  3215. jnz IRM_Exit
  3216. cCall FreeSelector, <ax> ; free the selector we got...
  3217. mov ax, 1 ; return success
  3218. IRM_Exit:
  3219. cEnd
  3220. else
  3221. cProc IsROMModule, <FAR, PUBLIC>
  3222. cBegin <nogen>
  3223. xor ax, ax
  3224. retf 6
  3225. cEnd <nogen>
  3226. endif
  3227. if ROM
  3228. ;-----------------------------------------------------------------------;
  3229. ; IsROMFile
  3230. ;
  3231. ; Determines if a file is in ROM
  3232. ;
  3233. ; Entry:
  3234. ; Returns:
  3235. ; Registers Destroyed:
  3236. ;
  3237. ; History:
  3238. ; 8/8/91 -- vatsanp -- adapted this for true-type files in ROM
  3239. ; from IsROMModule [ craigc]
  3240. ; Wed 01-May-1991 13:11:38 -by- Craig A. Critchley [craigc]
  3241. ; Wrote it!
  3242. ;-----------------------------------------------------------------------;
  3243. cProc IsROMFile, <FAR, PUBLIC>, <si, di>
  3244. parmD lpFile
  3245. parmD lpfsize
  3246. parmW fSelector
  3247. localV szName, 18
  3248. cBegin
  3249. cld
  3250. mov cx, 13
  3251. push ds
  3252. push ss
  3253. pop es
  3254. lea di, szName
  3255. assumes ds,nothing
  3256. lds si, lpFile
  3257. skip_spc: ; skip leading spaces
  3258. cmp byte ptr [si], ' '
  3259. jnz fnd_it
  3260. inc si
  3261. jmp short skip_spc
  3262. path_chr:
  3263. pop ds
  3264. xor ax, ax
  3265. jmp short IRF_Exit
  3266. fnd_it: ; if : / or \, not in ROM
  3267. lodsb
  3268. cmp al, ':'
  3269. jz path_chr
  3270. cmp al, '\'
  3271. jz path_chr
  3272. cmp al, '/'
  3273. jz path_chr
  3274. cmp al, ' ' ; if illegal character, end of path
  3275. jbe end_chr
  3276. cmp al, '<'
  3277. jz end_chr
  3278. cmp al, '>'
  3279. jz end_chr
  3280. cmp al, '|'
  3281. jz end_chr
  3282. stosb ; store up to 13 chars
  3283. loop fnd_it
  3284. end_chr:
  3285. mov byte ptr es:[di], 0 ; 0 terminate...
  3286. pop ds ; get DS back
  3287. lea ax, szName ; find file start in ROMTOC
  3288. cCall FindROMFile, <ss, ax, lpfsize>
  3289. or ax, ax
  3290. jz IRF_Exit
  3291. IRF_Found:
  3292. cmp fSelector,0
  3293. jnz IRF_Exit
  3294. cCall FreeSelector, <ax> ; free the selector we got...
  3295. mov ax, 1 ; return success
  3296. IRF_Exit:
  3297. cEnd
  3298. else
  3299. cProc IsROMFile, <FAR, PUBLIC>
  3300. cBegin <nogen>
  3301. xor ax, ax
  3302. retf 6
  3303. cEnd <nogen>
  3304. endif
  3305. sEnd NRESCODE
  3306. end