Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2855 lines
90 KiB

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