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.

845 lines
29 KiB

  1. TITLE LDHEADER - Load Exe Header procedure
  2. .xlist
  3. include gpfix.inc
  4. include kernel.inc
  5. include newexe.inc
  6. .list
  7. externA __AHINCR
  8. externFP IGlobalAlloc
  9. externFP IGlobalFree
  10. externFP FarSetOwner
  11. externFP Int21Handler
  12. externFP FarMyUpper
  13. externFP IsBadStringPtr
  14. externFP _hread
  15. DataBegin
  16. externB fBooting
  17. externB szBozo
  18. externW winVer
  19. externD pSErrProc
  20. DataEnd
  21. externFP IGlobalLock
  22. externFP IGlobalUnLock
  23. sBegin NRESCODE
  24. assumes CS,NRESCODE
  25. externNP NResGetPureName
  26. ;-----------------------------------------------------------------------;
  27. ; LoadExeHeader ;
  28. ; ;
  29. ; Routine to read an EXE header and check for a new format EXE file. ;
  30. ; Returns NULL if not a new format EXE. Otherwise reads the resident ;
  31. ; portion of the new EXE header into allocated storage and returns ;
  32. ; the segment address of the new EXE header. ;
  33. ; ;
  34. ; Arguments: ;
  35. ; parmW fh ;
  36. ; parmW isfh ;
  37. ; parmD pfilename ;
  38. ; ;
  39. ; Returns: ;
  40. ; AX = segment of exe header ;
  41. ; DL = ne_exetyp ;
  42. ; DH = ne_flagsothers ;
  43. ; ;
  44. ; Error Returns: ;
  45. ;LME_MEM = 0 ; Out of memory ;
  46. ;LME_VERS = 10 ; Wrong windows version ;
  47. ;LME_INVEXE = 11 ; Invalid exe ;
  48. ;LME_OS2 = 12 ; OS/2 app ;
  49. ;LME_DOS4 = 13 ; DOS 4 app ;
  50. ;LME_EXETYPE = 14 ; unknown exe type ;
  51. ;LME_COMP = 19 ; Compressed EXE file ;
  52. ;LME_PE = 21 ; Portable EXE ;
  53. ; ;
  54. ; Registers Preserved: ;
  55. ; DI,SI ;
  56. ; ;
  57. ; Registers Destroyed: ;
  58. ; AX,BX,CX,DS,ES ;
  59. ; Calls: ;
  60. ; ;
  61. ; History: ;
  62. ; ;
  63. ; Thu Mar 19, 1987 08:35:32p -by- David N. Weise [davidw] ;
  64. ; Added this nifty comment block. ;
  65. ;-----------------------------------------------------------------------;
  66. cProc LoadExeHeader,<PUBLIC,FAR>,<si,di>
  67. parmW fh
  68. parmW isfh
  69. parmD pfilename
  70. localW pnewexe
  71. localW exetype
  72. localW nchars
  73. localW pseg
  74. localW psegsrc
  75. localW hBlock
  76. localW pBlock
  77. localW NEFileOffset
  78. localD PreloadLen
  79. localW NEBase
  80. localW exeflags
  81. localW expver
  82. localW saveSP
  83. localB fast_fail ; 1 if we can't use fastload block
  84. localV hdrbuf,<SIZE EXE_HDR>
  85. .errnz SIZE EXE_HDR - SIZE NEW_EXE
  86. cBegin
  87. xor ax,ax
  88. mov pseg,ax
  89. mov hBlock, ax
  90. mov fast_fail, al
  91. cmp SEG_pfilename,ax
  92. je re0
  93. IF KDEBUG ; LoadExeHeader is internal
  94. cCall IsBadStringPtr, <pfilename, 128> ; so we assume file pointer is OK
  95. or ax, ax
  96. jnz refailj
  97. ENDIF
  98. lds si,pfilename
  99. mov al,ds:[si].opLen
  100. inc ax ; include null byte
  101. re0:
  102. mov nchars,ax
  103. mov bx,fh ; No, seek backwards over what
  104. cmp isfh,bx
  105. je refile
  106. mov ds,bx
  107. xor si,si
  108. jmp remem
  109. refile: ; Here to load from a file
  110. push ss ; DS:SI points to I/O buffer
  111. pop ds
  112. lea si,hdrbuf ; Read beginning of file
  113. mov dx,si
  114. mov cx,SIZE EXE_HDR
  115. mov bx,fh
  116. mov ah,3Fh
  117. DOSFCALL
  118. jnc @F
  119. refailj:
  120. jmps refail
  121. @@:
  122. cmp ax,cx ; Old EXE file, look for offset
  123. jb refailj ; to new exe header
  124. cmp ds:[si].e_magic,EMAGIC ; Check for old exe file
  125. je @F
  126. cmp ds:[si], 'ZS' ; Is it compressed?
  127. jne refail
  128. cmp ds:[si][2],'DD'
  129. jne refail
  130. cmp ds:[si][4],0F088h
  131. jne refail
  132. cmp ds:[si][6],03327h
  133. jne refail
  134. mov ax, LME_COMP ; Compressed EXE
  135. jmp reexit
  136. @@:
  137. mov ax,ds:[si].e_lfanew.hi
  138. mov dx,ds:[si].e_lfanew.lo
  139. mov pnewexe,dx ; To check for bound OS/2 apps.
  140. or ax,dx
  141. jz refail ; Fail if not there.
  142. mov cx,ds:[si].e_lfanew.hi
  143. mov dx,ds:[si].e_lfanew.lo
  144. mov bx, fh
  145. mov ax,4200h
  146. DOSFCALL
  147. jc refail
  148. mov cx,SIZE NEW_EXE
  149. mov dx,si
  150. mov ah,3Fh
  151. DOSFCALL
  152. jc refail
  153. cmp ax,cx
  154. jne refail
  155. cmp ds:[si].ne_magic,NEMAGIC ; Did we get a valid new EXE header?
  156. je remem
  157. cmp ds:[si].ne_magic,PEMAGIC ; Did we find a Portable EXE (WIN32)
  158. jne refail
  159. mov ax, LME_PE
  160. jmps rej
  161. refail:
  162. mov ax, LME_INVEXE ; invalid NEW EXE file format
  163. rej: jmp reexit
  164. remem:
  165. mov psegsrc,bx ; bx has either fh or seg address
  166. mov di,ds:[si].ne_enttab ; Compute size of resident new header
  167. add di,ds:[si].ne_cbenttab
  168. add di, 6 ; null entry space (bug #8414)
  169. mov cx, ds:[si].ne_cbenttab
  170. mov bx, ds:[si].ne_cmovent
  171. shl bx, 1
  172. sub cx, bx
  173. shl bx, 1
  174. sub cx, bx ; Number of bytes not moveable entries
  175. shl cx, 1 ; Allow triple these bytes
  176. add di, cx
  177. mov cx,ds:[si].ne_cseg ; + 3 * #segments
  178. ; Reserve space for ns_handle field in segment table
  179. shl cx,1
  180. add di,cx
  181. .errnz 10 - SIZE NEW_SEG1
  182. ; Reserve space for file info block at end
  183. add di,nchars ; + size of file info block
  184. xor ax,ax ; Allocate a fixed block for header
  185. mov bx,GA_ZEROINIT or GA_MOVEABLE
  186. cCall IGlobalAlloc,<bx,ax,di> ; that isn't code or data.
  187. or ax,ax
  188. jnz @F
  189. jmps badformat
  190. @@:
  191. push ax
  192. cCall IGlobalLock,<ax>
  193. pop ax
  194. push dx
  195. cCall IGlobalUnlock,<ax>
  196. pop ax
  197. sub di,nchars
  198. mov pseg,ax
  199. mov es,ax ; ES:0 -> new header location
  200. cld ; DS:SI -> old header
  201. mov bx,psegsrc
  202. cmp isfh,bx ; Is header in memory?
  203. jne remem1 ; Yes, continue
  204. mov ax,ds:[si].ne_enttab ; No, read into high end
  205. add ax,ds:[si].ne_cbenttab ; of allocated block
  206. sub di,ax
  207. mov cx,SIZE NEW_EXE ; Copy part read so far
  208. sub ax,cx
  209. rep movsb
  210. mov cx,ax
  211. smov ds,es ; Read rest of header from file
  212. mov dx,di
  213. mov ah,3fh
  214. DOSFCALL
  215. mov bx,ax
  216. jc refail1
  217. lea si,[di-SIZE NEW_EXE] ; DS:SI -> old header
  218. cmp bx,cx
  219. je remem1
  220. badformat:
  221. mov ax, LME_INVEXE ; don't change flags
  222. refail1: ; Here if error reading header
  223. push ax
  224. SetKernelDSNRes ; DS may be = pseg, prevent
  225. cCall IGlobalFree,<pseg> ; GP faults in pmode.
  226. pop ax
  227. jmp reexit
  228. remem1:
  229. UnsetKernelDS
  230. test ds:[si].ne_flags,NEIERR ; Errors in EXE image?
  231. jnz badformat ; Yes, fail
  232. cmp ds:[si].ne_ver,4 ; No, built by LINK4 or above?
  233. jl badformat ; No, error
  234. mov bx,ds:[si].ne_flags ; Make local copies of ne_flags &
  235. and bl,NOT NEPROT ; ne_expver which can be modified
  236. mov exeflags,bx ; (can't change ROM exe headers).
  237. mov bx,ds:[si].ne_expver
  238. mov expver,bx
  239. mov bx,word ptr ds:[si].ne_exetyp ; get exetyp and flagsothers
  240. mov exetype,bx
  241. cmp bl,NE_UNKNOWN
  242. jz windows_exe
  243. cmp bl,NE_WINDOWS ; is it a Windows exe?
  244. jz windows_exe
  245. mov ax,LME_OS2
  246. cmp bl,NE_OS2 ; is it an OS|2 exe?
  247. jnz not_os2
  248. test bh,NEINPROT ; can it be run under Windows?
  249. jz @F
  250. and exeflags,NOT NEAPPLOADER
  251. or exeflags,NEPROT
  252. mov expver,0300h
  253. jmps windows_exe
  254. @@:
  255. cmp pnewexe,0800h ; is it a bound
  256. jb refail1
  257. jmp badformat
  258. not_os2:
  259. inc ax ; AX = 13 - LME_DOS4
  260. cmp bl,NE_DOS4 ; is it a DOS 4 exe?
  261. jz refail1
  262. inc ax ; AX = 14 - LME_EXETYPE
  263. jmp refail1
  264. mgxlib DB 'MGXLIB'
  265. windows_exe:
  266. mov NEBase, si ; Offset of Source header
  267. xor di,di ; ES:DI -> new header location
  268. mov cx,SIZE NEW_EXE ; Copy fixed portion of header
  269. cld
  270. rep movsb
  271. mov ax,exeflags
  272. mov es:[ne_flags],ax
  273. mov ax,expver
  274. mov es:[ne_expver],ax
  275. mov si, NEBase
  276. add si, es:[ne_segtab] ; Real location of segment table
  277. mov cx,es:[ne_cseg] ; Copy segment table, adding
  278. mov es:[ne_segtab],di
  279. jcxz recopysegx
  280. recopyseg:
  281. movsw ; ns_sector
  282. movsw ; ns_cbseg
  283. lodsw ; ns_flags
  284. .errnz 4 - ns_flags
  285. and ax,not (NS286DOS XOR NSGETHIGH) ; Clear 286DOS bits
  286. ; record in the segment flags if this module is a process, this is for EMS
  287. test ax,NSTYPE ; NSCODE
  288. jnz not_code
  289. or ax,NSWINCODE
  290. not_code:
  291. or ax,NSNOTP
  292. test es:[ne_flags],NSNOTP
  293. jnz not_a_process
  294. xor ax,NSNOTP
  295. or ax,NSMOVE
  296. not_a_process:
  297. stosw ; ns_flags
  298. movsw ; ns_minalloc
  299. .errnz 8 - SIZE NEW_SEG
  300. xor ax,ax
  301. stosw ; one word for ns_handle field
  302. .errnz 10 - SIZE NEW_SEG1
  303. loop recopyseg
  304. recopysegx:
  305. test es:[ne_flagsothers], NEGANGLOAD
  306. jz no_gang_loadj
  307. mov bx, fh
  308. cmp bx, isfh
  309. jne no_gang_loadj
  310. mov ax, es:[ne_gang_start]
  311. or ax, ax
  312. jz no_gang_loadj
  313. mov NEFileOffset, ax ; file offset of gang load area
  314. mov ax, es:[ne_gang_length]
  315. or ax, ax
  316. jz no_gang_loadj
  317. mov cx, es:[ne_align]
  318. xor dx, dx
  319. gl_len: ; find length of Gang Load area
  320. shl ax, 1
  321. adc dx, dx
  322. loop gl_len
  323. cmp dx, 10h ; Greater than 1Mb, forget it!!
  324. jb alloc_it ; PS: NEVER go bigger than 1Mb
  325. no_gang_loadj:
  326. jmp no_gang_load ; since LongPtrAdd is limited...
  327. alloc_it:
  328. mov word ptr PreloadLen[0], ax
  329. mov word ptr PreloadLen[2], dx
  330. mov ch, GA_DISCARDABLE
  331. mov cl, GA_MOVEABLE+GA_NODISCARD+GA_NOCOMPACT
  332. push es
  333. cCall IGlobalAlloc,<cx,dx,ax> ; Allocate this much memory
  334. pop es
  335. or ax, ax
  336. jz no_gang_loadj
  337. mov hBlock, ax ; Have memory to read file into
  338. push es
  339. cCall IGlobalLock,<ax>
  340. pop es
  341. mov pBlock, dx
  342. mov dx, NEFileOffset
  343. mov cx, es:[ne_align]
  344. xor bx, bx
  345. gl_pos: ; find pos of Gang Load start
  346. shl dx, 1
  347. adc bx, bx
  348. loop gl_pos
  349. mov cx, bx
  350. mov bx, fh
  351. mov ax,4200h
  352. DOSFCALL ; Seek to new exe header
  353. jc refailgang
  354. mov ax, pBlock
  355. xor bx, bx
  356. farptr memadr,ax,bx
  357. cCall _hread, <fh, memadr, PreloadLen>
  358. cmp dx, word ptr PreloadLen[2]
  359. jnz refailgang
  360. cmp ax, word ptr PreloadLen[0]
  361. jz no_gang_load ; We're OK now
  362. ; push ds
  363. ; xor dx, dx
  364. ; mov ax, pBlock
  365. ; push si
  366. ; push di
  367. ; mov si, word ptr PreloadLen[2]
  368. ; mov di, word ptr PreloadLen[0]
  369. ;read_file:
  370. ; mov cx, 08000h ; Must be factor 64k DON'T CHANGE THIS
  371. ; or si, si
  372. ; jnz big_read
  373. ; cmp cx, di
  374. ; jbe big_read
  375. ; mov cx, di ; all that's left
  376. ; jcxz done_read ; Nothing left, quit.
  377. ;big_read:
  378. ; mov ds, ax
  379. ; mov ah, 3Fh
  380. ; DOSFCALL ; Read chunk from file
  381. ; jc refailgang
  382. ; cmp ax, cx ; All we asked for?
  383. ; jne refailgang ; no, file corrupted
  384. ; sub di, cx
  385. ; sbb si, 0
  386. ; mov ax, ds
  387. ; add dx, cx ; On to next block
  388. ; jnc read_file
  389. ; add ax, __AHINCR
  390. ; jmps read_file
  391. ;
  392. refailgang:
  393. ; pop di
  394. ; pop si
  395. ; pop ds
  396. cCall IGlobalUnlock,<hBlock>
  397. cCall IGlobalFree,<hBlock>
  398. mov hBlock, 0
  399. jmps no_gang_load
  400. BadExeHeader: ; GP fault handler!!!
  401. mov sp, saveSP
  402. ; fix_fault_stack
  403. jmp refail1 ; corrupt exe header (or our bug)
  404. ;done_read:
  405. ; pop di
  406. ; pop si
  407. ; pop ds
  408. no_gang_load:
  409. mov saveSP, sp
  410. beg_fault_trap BadExeHeader
  411. mov cx,es:[ne_restab] ; Copy resource table
  412. sub cx,es:[ne_rsrctab]
  413. mov si, NEBase ; Get correct source address
  414. add si, es:[ne_rsrctab]
  415. mov es:[ne_rsrctab],di
  416. rep movsb
  417. rerestab:
  418. mov cx,es:[ne_modtab] ; Copy resident name table
  419. sub cx,es:[ne_restab]
  420. mov es:[ne_restab],di
  421. rep movsb
  422. push di
  423. mov di, es:[ne_restab] ; Make the module name Upper Case
  424. xor ch, ch
  425. mov cl, es:[di]
  426. inc di
  427. uppercaseit:
  428. mov al, es:[di]
  429. call farMyUpper
  430. stosb
  431. loop uppercaseit
  432. pop di
  433. mov cx,es:[ne_imptab] ; Copy module xref table
  434. sub cx,es:[ne_modtab]
  435. mov es:[ne_modtab],di
  436. rep movsb
  437. mov es:[ne_psegrefbytes],di ; Insert segment reference byte table
  438. mov es:[ne_pretthunks],di ; Setup return thunks
  439. mov cx,es:[ne_enttab] ; Copy imported name table
  440. sub cx,es:[ne_imptab]
  441. mov es:[ne_imptab],di
  442. jcxz reenttab
  443. rep movsb
  444. reenttab:
  445. mov es:[ne_enttab],di
  446. ; Scan current entry table
  447. xor ax, ax ; First entry in block
  448. mov bx, di ; Pointer to info for this block
  449. stosw ; Starts at 0
  450. stosw ; Ends at 0
  451. stosw ; And is not even here!
  452. copy_next_block:
  453. lodsw ; Get # entries and type
  454. xor cx, cx
  455. mov cl, al
  456. jcxz copy_ent_done
  457. mov al, ah
  458. cmp al, ENT_UNUSED
  459. jne copy_used_block
  460. mov ax, es:[bx+2] ; Last entry in current block
  461. cmp ax, es:[bx] ; No current block?
  462. jne end_used_block
  463. add es:[bx], cx
  464. add es:[bx+2], cx
  465. jmps copy_next_block
  466. end_used_block:
  467. mov es:[bx+4], di ; Pointer to next block
  468. mov bx, di
  469. add ax, cx ; Skip unused entries
  470. stosw ; First in new block
  471. stosw ; Last in new block
  472. xor ax, ax
  473. stosw ; End of list
  474. jmps copy_next_block
  475. copy_used_block:
  476. add es:[bx+2], cx ; Add entries in this block
  477. cmp al, ENT_MOVEABLE
  478. je copy_moveable_block
  479. ; absolutes end up here as well
  480. copy_fixed_block:
  481. stosb ; Segno
  482. movsb ; Flag byte
  483. stosb ; segno again to match structure
  484. movsw ; Offset
  485. loop copy_fixed_block
  486. jmps copy_next_block
  487. copy_moveable_block:
  488. stosb ; ENT_MOVEABLE
  489. movsb ; Flag byte
  490. add si, 2 ; Toss int 3Fh
  491. movsb ; Copy segment #
  492. movsw ; and offset
  493. loop copy_moveable_block
  494. jmps copy_next_block
  495. copy_ent_done:
  496. xor bx,bx
  497. cmp es:[bx].ne_ver,5 ; Produced by version 5.0 LINK4
  498. jae remem2a ; or above?
  499. mov es:[bx].ne_expver,bx ; No, clear uninitialized fields
  500. mov es:[bx].ne_swaparea,bx
  501. ; TEMPORARY BEGIN
  502. push ax
  503. push cx
  504. push di
  505. push si
  506. mov si,es:[bx].ne_rsrctab
  507. cmp si,es:[bx].ne_restab
  508. jz prdone
  509. mov di,es:[si].rs_align
  510. add si,SIZE new_rsrc
  511. prtype:
  512. cmp es:[si].rt_id,0
  513. je prdone
  514. mov cx,es:[si].rt_nres
  515. add si,SIZE rsrc_typeinfo
  516. prname:
  517. push cx
  518. mov ax,es:[si].rn_flags
  519. test ah,0F0h ; Is old discard field set?
  520. jz @F
  521. or ax,RNDISCARD ; Yes, convert to bit
  522. @@:
  523. and ax,not RNUNUSED ; Clear unused bits in 4.0 LINK files
  524. mov es:[si].rn_flags,ax
  525. pop cx
  526. add si,SIZE rsrc_nameinfo
  527. loop prname
  528. jmp prtype
  529. prdone: pop si
  530. pop di
  531. pop cx
  532. pop ax
  533. ; TEMPORARY END
  534. FixFlags: ; label for debugging
  535. public FixFlags, leh_slow
  536. public leh_code, leh_patchnext, leh_code_fixed, leh_patchdone, leh_data
  537. remem2a: ; (bx == 0)
  538. mov es:[bx].ne_usage,bx
  539. mov es:[bx].ne_pnextexe,bx
  540. mov es:[bx].ne_pfileinfo,bx
  541. cmp es:[bx].ne_align,bx
  542. jne @F
  543. mov es:[bx].ne_align,NSALIGN
  544. @@:
  545. mov cx,nchars
  546. jcxz @F
  547. mov es:[bx].ne_pfileinfo,di
  548. lds si,pfilename
  549. rep movsb
  550. @@: ; Save pointer to seginfo record
  551. mov bx,es:[bx].ne_autodata ; of automatic data segment
  552. or bx,bx
  553. jz @F
  554. dec bx
  555. shl bx,1
  556. mov cx,bx
  557. shl bx,1
  558. shl bx,1
  559. add bx,cx
  560. .errnz 10 - SIZE NEW_SEG1
  561. add bx,es:[ne_segtab]
  562. @@:
  563. mov es:[ne_pautodata],bx
  564. SetKernelDSNRes
  565. ; Scan seg table, marking nonautomatic DATA segments fixed, preload
  566. mov ax,es:[ne_expver] ; Default expected version to
  567. or ax,ax
  568. jnz @F
  569. mov ax,201h
  570. mov es:[ne_expver],ax ; 2.01
  571. @@:
  572. cmp ax,winVer
  573. jbe @F
  574. cCall IGlobalFree,<pseg>
  575. mov ax, LME_VERS
  576. jmp reexit
  577. @@:
  578. mov bx,es:[ne_segtab]
  579. xor cx,cx
  580. sub bx,SIZE NEW_SEG1
  581. jmps leh_patchnext
  582. leh_test_preload:
  583. test byte ptr es:[bx].ns_flags, NSPRELOAD
  584. jnz leh_patchnext
  585. or byte ptr es:[bx].ns_flags, NSPRELOAD
  586. cmp es:[bx].ns_sector, 0 ; don't whine about empty segments
  587. je leh_patchnext
  588. krDebugOut DEB_WARN, "Segment #CX of %ES0 must be preload"
  589. mov fast_fail, 1
  590. leh_patchnext:
  591. add bx,SIZE NEW_SEG1
  592. inc cx
  593. cmp cx,es:[ne_cseg]
  594. ja leh_patchdone
  595. test byte ptr es:[bx].ns_flags,NSDATA ; Is it a code segment?
  596. jz leh_code ; Yes, next segment
  597. .errnz NSCODE
  598. leh_data: ; Data must be non-discardable, preload
  599. if KDEBUG
  600. test es:[bx].ns_flags, NSDISCARD
  601. jz @F
  602. krDebugOut DEB_WARN, "Data Segment #CX of %ES0 can't be discardable"
  603. @@:
  604. endif
  605. and es:[bx].ns_flags,not NSDISCARD ; Data segments not discardable
  606. jmps leh_test_preload
  607. leh_code:
  608. test byte ptr es:[bx].ns_flags,NSMOVE; Moveable code?
  609. jz leh_code_fixed
  610. ; moveable code must be discardable, or must be preload
  611. if KDEBUG
  612. test es:[ne_flags],NENOTP ; for 3.0 libraries can't have
  613. jz @F ; moveable only code
  614. cmp fBooting,0 ; If not booting
  615. jne @F
  616. test es:[bx].ns_flags,NSDISCARD
  617. jnz @F
  618. krDebugOut DEB_WARN, "Segment #CX of %ES0 was discardable under Win 3.0"
  619. @@:
  620. endif
  621. test es:[bx].ns_flags,NSDISCARD ; Is it discardable?
  622. jnz leh_patchnext
  623. jmp leh_test_preload
  624. leh_code_fixed: ; fixed code must be preload
  625. cmp fBooting,0 ; If not booting
  626. jne leh_patchnext
  627. jmp leh_test_preload
  628. leh_patchdone:
  629. mov bx,word ptr es:[ne_csip+2] ; Is there a start segment?
  630. or bx,bx
  631. jz @F ; No, continue
  632. dec bx
  633. shl bx,1
  634. mov si,bx
  635. shl si,1
  636. shl si,1
  637. add si,bx
  638. .errnz 10 - SIZE NEW_SEG1
  639. add si,es:[ne_segtab] ; Mark start segment as preload
  640. if kdebug
  641. test byte ptr es:[si].ns_flags,NSPRELOAD
  642. jnz scs_pre
  643. krDebugOut DEB_WARN, "Starting Code Segment of %ES0 must be preload"
  644. mov fast_fail, 1
  645. scs_pre:
  646. endif
  647. or byte ptr es:[si].ns_flags,NSPRELOAD
  648. cmp es:[ne_autodata],0 ; Is there a data segment?
  649. je @F
  650. or es:[si].ns_flags,NSUSESDATA ; Yes, then it needs it
  651. mov si,es:[ne_pautodata]
  652. if kdebug
  653. test byte ptr es:[si].ns_flags,NSPRELOAD
  654. jnz sds_pre
  655. cmp es:[bx].ns_sector, 0 ; don't whine about empty segments
  656. je sds_pre
  657. krDebugOut DEB_WARN, "Default Data Segment of %ES0 must be preload"
  658. mov fast_fail, 1
  659. sds_pre:
  660. endif
  661. or byte ptr es:[si].ns_flags,NSPRELOAD ; Mark DS as preload
  662. @@:
  663. test es:[ne_flags],NENOTP ; No stack if not a process
  664. jnz @F
  665. cmp es:[ne_stack],4096+1024
  666. jae @F
  667. mov es:[ne_stack],4096+1024 ; 4k stack is not enough (raor)
  668. @@:
  669. mov cx, es:[ne_heap] ; If the module wants a heap
  670. jcxz leh_heapadjdone ; make sure it's big enough
  671. mov ax, 800h ; ; Environment variables have
  672. cmp cx, ax ; grown, so we need more heap
  673. jae leh_heapadjdone ; space for apps so we use 800h
  674. mov dx, ax
  675. test es:[ne_flags],NENOTP
  676. jnz @F
  677. add dx, es:[ne_stack]
  678. jc leh_heapadjmin
  679. @@:
  680. mov bx,es:[ne_autodata] ; set if no autodata segment
  681. or bx,bx ; we have to do this here
  682. jz leh_heapadjset ; because for certain dlls
  683. dec bx ; pautodata is not initialized
  684. shl bx,1
  685. mov cx,bx
  686. shl bx,1
  687. shl bx,1
  688. add bx,cx
  689. add bx,es:[ne_segtab]
  690. add dx, es:[bx].ns_minalloc
  691. jnc leh_heapadjset
  692. leh_heapadjmin:
  693. ; if 800h is too big fallback to
  694. if KDEBUG ; what win9x code used as minimum
  695. mov ax, 100h + SIZE LocalStats ; heap size 100h
  696. else
  697. mov ax, 100h
  698. endif
  699. mov cx, es:[ne_heap]
  700. cmp cx, ax
  701. jae leh_heapadjdone
  702. leh_heapadjset:
  703. mov es:[ne_heap], ax
  704. leh_heapadjdone:
  705. mov ax,es ; Set owner to be itself
  706. cCall FarSetOwner,<ax,ax>
  707. mov dx,exetype
  708. test dh,NEINFONT ; save the font bit in exehdr
  709. jz reexit ; somewhere
  710. or es:[ne_flags],NEWINPROT
  711. end_fault_trap
  712. reexit:
  713. ; cmp ax, 20h ; translate error messages for ret
  714. ; jae @F
  715. ; mov bx, ax
  716. ; xor ax, ax
  717. ; cmp bl, 1 ; bx is 0, 1, 2, 19, other
  718. ; jz @F ; 1 -> 0 (out of memory)
  719. ; mov al, 11
  720. ; jb @F ; 0 -> 11 (invalid format)
  721. ; cmp bl, 3 ;
  722. ; mov al, 10
  723. ; jb @F ; 2 -> 10 (windows version)
  724. ; mov al, 19 ; 3 -> 19 (compressed EXE)
  725. ; jz @F ; others left alone
  726. ; mov al, bl
  727. ;@@:
  728. push dx
  729. mov bx, hBlock
  730. or bx, bx
  731. je noUnlock ; No block to unlock
  732. push ax
  733. cCall IGlobalUnlock,<bx>
  734. push ss
  735. pop ds ; might be freeing DS
  736. cmp fast_fail, 1 ; is fastload area invalid?
  737. jne @F
  738. leh_slow:
  739. krDebugOut DEB_WARN, "FastLoad area ignored due to incorrect segment flags"
  740. cCall IGlobalFree,<hBlock> ; yes - free it, force slow-load
  741. mov hBlock, 0
  742. @@:
  743. pop ax
  744. cmp ax, LME_MAXERR
  745. jae noFree ; Success, return memory block in bx
  746. push ax
  747. cCall IGlobalFree,<hBlock>
  748. pop ax
  749. noFree:
  750. mov cx, NEFileOffset ; Return offset of header in CX
  751. mov bx, hBlock
  752. noUnlock:
  753. pop dx
  754. UnSetKernelDS
  755. cEnd
  756. sEnd NRESCODE
  757. end