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.

1626 lines
55 KiB

  1. TITLE LDSEG - SegAlloc procedure
  2. .xlist
  3. include kernel.inc
  4. include newexe.inc
  5. include tdb.inc
  6. include protect.inc ; Handle_To_Sel
  7. .list
  8. NSHUGESEG = NSKCACHED ; not first seg of huge segment
  9. ; A huge segment (data object larger than 64K) requires more than one
  10. ; selector, but is part of a single memory allocation block. The first
  11. ; selector is a handle, like any other segment. Subsequent selectors of
  12. ; the huge memory block are _not_ handles, so we can't call MyLock() on
  13. ; them, as the consistency check will fail. We mark these selectors with
  14. ; the NSHUGESEG bit in the flags word. TonyG suggested this.
  15. ; Note that data segments are already loaded, locked, etc, so the call to
  16. ; MyLock is redundant anyway.
  17. ; Thu Feb 28, 1991 01:39:00p -by- Don A. Corbitt [donc] ;
  18. externFP IGlobalFree
  19. externFP IGlobalAlloc
  20. externFP IGlobalReAlloc
  21. externFP IGlobalLock
  22. externFP MyOpenFile
  23. externFP FlushCachedFileHandle
  24. externFP Int21Handler
  25. externFP set_discarded_sel_owner
  26. externFP GetPatchAppRegKey
  27. externFP PatchAppSeg
  28. if KDEBUG
  29. externFP OutputDebugString
  30. endif
  31. DataBegin
  32. externB Kernel_flags
  33. ;externB fBooting
  34. externB fPadCode
  35. ;externW pGlobalHeap
  36. ;externW MyCSDS
  37. externW Win_PDB
  38. if KDEBUG
  39. externB fLoadTrace
  40. externB fPreloadSeg
  41. endif
  42. externD FreeArenaCount
  43. extrn CountFreeSel:WORD
  44. DataEnd
  45. sBegin CODE
  46. assumes CS,CODE
  47. assumes DS,NOTHING
  48. assumes ES,NOTHING
  49. ;externNP MyFree
  50. externNP SegReloc
  51. externNP MyAlloc
  52. externNP MyAllocLinear ; MyAlloc with useful parameters
  53. externNP MyLock
  54. externNP GetCachedFileHandle
  55. externNP CloseCachedFileHandle
  56. externNP GetOwner
  57. externNP SetOwner
  58. externNP get_selector_length16
  59. externNP get_rover_2
  60. externNP DiscardTheWorld
  61. IFNDEF NO_APPLOADER
  62. externNP LoadApplSegment
  63. endif ;!NO_APPLOADER
  64. if LDCHKSUM
  65. ;externNP GetChksumAddr
  66. externNP CheckSegChksum
  67. externNP ZeroSegmentChksum
  68. endif
  69. if SDEBUG
  70. externNP DebugDefineSegment
  71. endif
  72. ifdef WOW_x86
  73. externNP get_physical_address
  74. endif
  75. ;-----------------------------------------------------------------------;
  76. ; AllocSeg ;
  77. ; ;
  78. ; Allocates memory for a segment. Does not load the segment. Puts ;
  79. ; the handle of the segment into the segment descriptor structure ;
  80. ; in the module database, and updates the flags there to mark the ;
  81. ; segment as allocated but not loaded. Put the segment number into ;
  82. ; the BurgerMaster handle entry. It also changes the .ga_owner to be ;
  83. ; the module database. ;
  84. ; ;
  85. ; Arguments: ;
  86. ; parmD pSegInfo ;
  87. ; ;
  88. ; Returns: ;
  89. ; AX = handle for segment ;
  90. ; ;
  91. ; Error Returns: ;
  92. ; AX = 0 ;
  93. ; ZF = 1 ;
  94. ; ;
  95. ; Registers Preserved: ;
  96. ; SI,DS,ES ;
  97. ; ;
  98. ; Registers Destroyed: ;
  99. ; BX,CX,DX ;
  100. ; ;
  101. ; Calls: ;
  102. ; MyAlloc ;
  103. ; ;
  104. ; History: ;
  105. ; Thu Feb 28, 1991 01:39:00p -by- Don A. Corbitt [donc] ;
  106. ; Handle 64K (big/huge) data segments ;
  107. ; ; ;
  108. ; Mon Feb 09, 1987 10:29:16p -by- David N. Weise [davidw] ;
  109. ; Added this nifty comment block. ;
  110. ;-----------------------------------------------------------------------;
  111. assumes ds,nothing
  112. assumes es,nothing
  113. cProc AllocSeg,<PUBLIC,NEAR>,<si,es>
  114. parmD pSegInfo
  115. cBegin
  116. SetKernelDS
  117. les si,pSegInfo
  118. ; Get size into AX (max of file size and minimum allocation).
  119. mov bx,es:[si].ns_flags
  120. test bl,NSALLOCED ; Already allocated?
  121. jz as0 ; No, allocate it
  122. jmp SHORT as3
  123. as0: mov ax,es:[si].ns_minalloc
  124. xor dx, dx ; if AX == 0
  125. cmp ax, 1 ; then it is really 64K
  126. adc dx, dx
  127. add ax, 2 ; We may have a 1 byte entry point at the
  128. adc dx, 0 ; very end of a segment. PatchCodeHandle
  129. ; will GP trying to decipher the prolog.
  130. ; Also allow space for reading relocation word
  131. cmp si,es:[ne_pautodata]
  132. jne as1
  133. add ax,es:[ne_stack] ; Include stack and heap for data.
  134. jc asfail ; Don't need to handle big auto segs
  135. add ax,es:[ne_heap]
  136. jnc as1
  137. asfail:
  138. krDebugOut DEB_ERROR, "%es2 Automatic Data Segment larger than 64K."
  139. xor ax,ax
  140. asxj: jmp SHORT asx
  141. as1:
  142. ; Allocate space for segment
  143. push bx
  144. push es
  145. cCall MyAllocLinear,<bx,dxax>
  146. pop es
  147. pop bx
  148. or ax,ax
  149. jz asxj
  150. as2:
  151. mov es:[si].ns_handle,dx ; Handle into seg table
  152. and byte ptr es:[si].ns_flags,not NSLOADED
  153. or byte ptr es:[si].ns_flags,NSALLOCED
  154. mov bx,dx
  155. cCall SetOwner,<ax,es>
  156. as3: mov ax,es:[si].ns_handle
  157. asx:
  158. or ax,ax
  159. cEnd
  160. ;-----------------------------------------------------------------------;
  161. ; LoadSegment ;
  162. ; ;
  163. ; Loads a segment and performs any necessary relocations. ;
  164. ; ;
  165. ; Arguments: ;
  166. ; parmW hExe ;
  167. ; parmW segno ;
  168. ; parmW fh ;
  169. ; parmW isfh ;
  170. ; ;
  171. ; Returns: ;
  172. ; AX = handle of segment ;
  173. ; CX = handle of segment ;
  174. ; DX = handle of segment ;
  175. ; ;
  176. ; Error Returns: ;
  177. ; AX = 0 ;
  178. ; CX = 0 ;
  179. ; ;
  180. ; Registers Preserved: ;
  181. ; DI,SI,DS ;
  182. ; ;
  183. ; Registers Destroyed: ;
  184. ; BX,ES ;
  185. ; ;
  186. ; Calls: ;
  187. ; LoadSegment ;
  188. ; AllocSeg ;
  189. ; LoadApplSegment ;
  190. ; MyOpenFile ;
  191. ; SegLoad ;
  192. ; GlobalAlloc ;
  193. ; MyLock ;
  194. ; SegReloc ;
  195. ; GlobalFree ;
  196. ; ZeroSegmentChksum ;
  197. ; CheckSegChksum ;
  198. ; ;
  199. ; History: ;
  200. ; Thu Feb 28, 1991 01:39:00p -by- Don A. Corbitt [donc] ;
  201. ; ;
  202. ; Tue Oct 27, 1987 06:10:31p -by- David N. Weise [davidw] ;
  203. ; Wrote it. ;
  204. ;-----------------------------------------------------------------------;
  205. assumes ds,nothing
  206. assumes es,nothing
  207. cProc LoadSegment,<PUBLIC,NEAR>,<si,di>
  208. parmW hExe
  209. parmW segno
  210. parmW fh
  211. parmW isfh
  212. localW myfh
  213. localW hrleseg
  214. localD pseginfo
  215. localW creloc
  216. localW hseg
  217. localW fdataseg
  218. localW retries
  219. localW SavePDB
  220. localB fReload
  221. localW pleaseNoLock ; 1 if shouldn't lock seg
  222. cBegin
  223. mov retries, 2
  224. xor ax,ax
  225. mov hrleseg,ax
  226. mov hseg,ax
  227. mov SavePDB, ax
  228. mov pleaseNoLock, ax
  229. mov fReload, al
  230. not ax
  231. mov myfh,ax
  232. mov es,hexe
  233. mov si,segno
  234. dec si
  235. cmp es:[ne_cseg],si
  236. jg ls_not_done ; wish we had auto jump sizing...
  237. jmp lsdone
  238. ls_not_done:
  239. shl si,1
  240. mov bx,si
  241. shl si,1
  242. shl si,1
  243. add si,bx
  244. .errnz 10 - SIZE NEW_SEG1
  245. add si,es:[ne_segtab]
  246. mov SEG_pseginfo, es ; Save segment info pointer
  247. mov OFF_pseginfo, si
  248. IFNDEF NO_APPLOADER
  249. test es:[ne_flags],NEAPPLOADER
  250. jnz ls_special_load
  251. ls_not_special_load:
  252. ENDIF ;!NO_APPLOADER
  253. mov bx,es:[si].ns_flags
  254. mov ax, bx
  255. and ax, NSHUGESEG
  256. mov pleaseNoLock, ax
  257. test bl,NSALLOCED
  258. jnz ls1
  259. push bx
  260. cCall AllocSeg,<essi> ; No, so try allocating the segment
  261. pop bx
  262. or ax,ax
  263. jnz ls1b
  264. ls1: mov ax,es:[si].ns_handle
  265. mov hseg,ax
  266. test bl,NSLOADED
  267. jz ls1b
  268. mov fReload,1
  269. jmp lsexit ; so MyLock at lsexit can swap them in
  270. IFNDEF NO_APPLOADER
  271. ls_special_load:
  272. mov ax,segno
  273. cmp ax,1
  274. je ls_not_special_load ;* first segment normal load
  275. test es:[si].ns_flags,NSLOADED
  276. jnz ls_already_loaded
  277. cCall LoadApplSegment, <hExe, fh, ax>
  278. jmp lsx
  279. ls_already_loaded:
  280. mov ax,es:[si].ns_handle
  281. mov hseg,ax
  282. mov fReload,1
  283. jmp lsexit
  284. endif ;!NO_APPLOADER
  285. ls1b:
  286. mov ax,fh
  287. inc ax ; Already have file handle?
  288. jz ls2 ; No, then get one and load segment
  289. dec ax
  290. cmp isfh,ax ; Yes, loading from memory?
  291. jne lsdoit ; Yes, load it now
  292. jmps ls2b ; No, load it now
  293. ls2:
  294. SetKernelDS
  295. mov ax, Win_PDB ; Save what PDB is supposed to be
  296. mov SavePDB, ax ; since we will set it to kernel's PDB
  297. mov ax,-1
  298. cCall GetCachedFileHandle,<hExe,ax,ax> ; Get file handle from cache
  299. ls2b:
  300. mov myfh,ax
  301. mov isfh,ax
  302. inc ax
  303. jnz lsdoit0
  304. cmp SavePDB, ax ; If we saved the PDB, (ax=0)
  305. je @F
  306. push SavePDB ; better restore it!
  307. pop Win_PDB
  308. @@:
  309. jmp lsdone
  310. lsdoit0:
  311. dec ax
  312. lsdoit:
  313. push es
  314. cCall SegLoad,<essi,segno,ax,isfh>
  315. pop es
  316. mov hseg,0
  317. or ax,ax
  318. jz lsexit1
  319. inc ax ; Did we get a file error?
  320. jnz lsloaded
  321. mov bx, myfh
  322. inc bx ; Reading from memory?
  323. jz lsexit1 ; no, fail
  324. dec bx
  325. cmp bx, fh ; We opened the file?
  326. je lsexit1 ; no, fail
  327. ;;; cCall CloseCachedFileHandle,<bx>
  328. mov bx, SavePDB
  329. mov Win_PDB, bx
  330. cCall FlushCachedFileHandle,<hExe> ; Close it
  331. dec retries
  332. jz lsbadfile
  333. jmps ls2 ; and try to re-open it.
  334. UnSetKernelDS
  335. lsbadfile:
  336. krDebugOut DEB_ERROR, "%ES2 I/O error reading segment"
  337. lsexit1:
  338. jmp lsexit
  339. lsloaded:
  340. mov hseg,bx
  341. mov bx,es:[si].ns_flags
  342. test bx,NSRELOC
  343. jnz lm1x
  344. jmp lschksum
  345. lm1x:
  346. and bx,NSDATA
  347. mov fdataseg,bx
  348. mov bx,myfh ; Loading from memory?
  349. inc bx
  350. jnz lm1 ; No, continue
  351. mov es,dx ; Yes, point to relocation info
  352. mov si,cx
  353. cld
  354. lods word ptr es:[si]
  355. mov creloc,ax
  356. jmps lm2
  357. lm1:
  358. dec bx
  359. mov creloc,cx
  360. shl cx,1
  361. shl cx,1
  362. shl cx,1
  363. .errnz 8 - SIZE new_rlc
  364. push bx
  365. push cx
  366. mov ax,GA_MOVEABLE+GA_NODISCARD ; DO NOT WANT FIXED!!
  367. xor bx,bx
  368. regptr xsize,bx,cx
  369. .386
  370. ; We don't really want to cause an attempt to grow the global arena
  371. ; table or the LDT here!
  372. push ds
  373. SetKernelDS
  374. cmp FreeArenaCount,0 ; free arena?
  375. jz NoFreeArenas ; No
  376. cmp CountFreeSel,0 ; free selector?
  377. NoFreeArenas:
  378. pop ds
  379. UnsetKernelDS
  380. jz lm1a ; No, then read one at a time
  381. .286
  382. cCall IGlobalAlloc,<ax,xsize>
  383. mov hrleseg,ax ; Save handle
  384. or ax,ax ; Did we get the memory
  385. jz lm1a ; No, then read one at a time
  386. cCall IGlobalLock,<ax> ; Get the address of the relocation info
  387. mov si, ax
  388. mov es, dx
  389. pop cx ; Restore byte count
  390. pop bx ; Restore file handle
  391. push ds
  392. mov ds,dx
  393. assumes ds,nothing
  394. xor dx,dx
  395. mov ah,3Fh ; Read in relocation information
  396. DOSCALL
  397. pop ds
  398. assumes ds,nothing
  399. jc lserr2
  400. cmp ax,cx
  401. jne lserr2
  402. jmps lm2
  403. lm1a:
  404. pop cx ; Restore byte count
  405. pop bx ; Restore file handle
  406. xor si,si
  407. mov es,si ; Signal no records read
  408. lm2:
  409. ; Pass pseginfo, not hseg
  410. cCall SegReloc,<hexe,essi,creloc,pseginfo,fdataseg,myfh>
  411. lm2a:
  412. mov cx,hrleseg
  413. jcxz no_hrleseg
  414. push ax
  415. cCall IGlobalFree,<hrleseg>
  416. pop ax
  417. no_hrleseg:
  418. les si,pseginfo
  419. or ax,ax
  420. jnz lschksum
  421. lsdone2:
  422. jmps lsdone
  423. lserr2:
  424. krDebugOut DEB_ERROR, "Error reading relocation records from %es2"
  425. xor ax,ax
  426. jmp lm2a
  427. lschksum:
  428. mov ax, hseg ; in case we aren't locking
  429. Handle_To_Sel al
  430. cmp pleaseNoLock, 0
  431. jnz lschksum1
  432. cCall MyLock,<hseg>
  433. lschksum1:
  434. if LDCHKSUM
  435. push ax
  436. push si
  437. mov si,ax
  438. cCall ZeroSegmentChksum
  439. pop si
  440. cCall CheckSegChksum ; destroys ax, bx, cx, dx, es
  441. pop ax
  442. endif
  443. les si, pseginfo
  444. if SDEBUG ; Tell debugger about new segment
  445. cmp pleaseNoLock, 0
  446. jnz keep_secrets
  447. mov bx,es:[ne_restab]
  448. inc bx
  449. mov dx,es:[si].ns_flags
  450. mov si, ax
  451. xor ax, ax
  452. test dx,NSDATA ; test to pass NSKCACHED too
  453. jz sa8
  454. test byte ptr es:[ne_flags],NEINST
  455. jz sa8
  456. mov ax,es:[ne_usage]
  457. dec ax
  458. sa8:
  459. mov cx,segno
  460. dec cx
  461. cCall DebugDefineSegment,<esbx,cx,si,ax,dx>
  462. keep_secrets:
  463. endif
  464. lsexit:
  465. mov cx,hseg
  466. jcxz lsdone
  467. mov ax, cx ; in case we don't lock
  468. mov dx, ax
  469. Handle_To_Sel al
  470. cmp pleaseNoLock, 0
  471. jnz lsdone
  472. cCall MyLock,<cx>
  473. lsdone:
  474. mov cx,myfh
  475. inc cx
  476. jz lsx
  477. dec cx
  478. cmp fh,cx
  479. je lsx
  480. push ax
  481. SetKernelDS
  482. ;;; cCall CloseCachedFileHandle,<cx>
  483. mov ax, SavePDB
  484. if KDEBUG
  485. or ax, ax
  486. jnz @F
  487. int 3
  488. @@:
  489. endif
  490. mov Win_PDB, ax
  491. UnSetKernelDS
  492. pop ax
  493. public lsx
  494. lsx:
  495. mov es, hExe
  496. test es:[ne_flagsothers], NEHASPATCH
  497. jz ls_exeunt
  498. cmp fReload, 0
  499. jne ls_exeunt
  500. push dx
  501. push ax
  502. cCall GetPatchAppRegKey,<hExe>
  503. mov cx, dx
  504. or cx, ax
  505. jnz @F
  506. ; MCF_MODPATCH is set, but there are no patches
  507. ; in the registry for this module. Turn off the patch flag.
  508. and es:[ne_flagsothers], not NEHASPATCH
  509. jmp short ls_after_patch
  510. @@:
  511. ; reg key in dx:ax
  512. cCall PatchAppSeg,<dx,ax,segno,hseg>
  513. test ax, ax
  514. jz ls_after_patch
  515. ; One or more patches applied, so mark the segment not discardable.
  516. ; PatchAppSeg already cleared GA_DISCARDABLE or GA_DISCCODE in the
  517. ; global arena record.
  518. mov si, pseginfo.off
  519. and es:[si].ns_flags, not NSDISCARD ; mark not discardable
  520. ls_after_patch:
  521. pop ax
  522. pop dx
  523. ls_exeunt:
  524. mov cx,ax
  525. cEnd
  526. GETSEGLEN macro segval
  527. local not_huge_386
  528. .386p
  529. xor eax, eax ; since we now have huge segments,
  530. mov ax, segval ; we need to be able to handle limit
  531. lsl eax, eax ; values > 64K. On a 386 we just
  532. inc eax ; execute the lsl instruction.
  533. test eax, 0ffff0000h
  534. .286
  535. jz not_huge_386
  536. mov ax, 0 ; 0 == 64K
  537. not_huge_386:
  538. endm
  539. ;-----------------------------------------------------------------------;
  540. ; SegLoad ;
  541. ; ;
  542. ; Reads in the data portion of a code or data segment. ;
  543. ; ;
  544. ; It can be confusing decoding how various values of ns_cbseg, ;
  545. ; ns_minalloc, and ns_sector define the size of disk files. I hope ;
  546. ; this table is accurate for all combinations.... ;
  547. ; ;
  548. ; sector cbseg minalloc- Sector in memory is ... ;
  549. ; 0 0 0 - 64K segment, all 0's ;
  550. ; 0 0 m - 'm' bytes, all 0's ;
  551. ; 0 c 0 - illegal (sector = 0 when cbseg != 0) ;
  552. ; 0 c m - illegal (sector = 0 when cbseg != 0) ;
  553. ; s 0 0 - 64K segment on disk at given sector ;
  554. ; s 0 m - illegal (cbseg > minalloc) ;
  555. ; s c 0 - 64K, 'c' from file, 64K-'c' 0's ;
  556. ; s c m - 'm' bytes, 'c' from file, 'm-c' 0's ;
  557. ; ;
  558. ; In other words, cbseg == 0 means 64K when a sector value is given, ;
  559. ; else it means 0 bytes from the file ;
  560. ; ;
  561. ; Arguments: ;
  562. ; parmD pseginfo ;
  563. ; parmW segno ;
  564. ; parmW psegsrc ;
  565. ; parmW isfh ;
  566. ; ;
  567. ; Returns: ;
  568. ; ;
  569. ; Error Returns: ;
  570. ; ;
  571. ; Registers Preserved: ;
  572. ; ;
  573. ; Registers Destroyed: ;
  574. ; ;
  575. ; Calls: ;
  576. ; ;
  577. ; History: ;
  578. ; Thu Feb 28, 1991 01:39:00p -by- Don A. Corbitt [donc] ;
  579. ; Add support for big/huge segments ;
  580. ; ;
  581. ; Tue Oct 27, 1987 06:17:07p -by- David N. Weise [davidw] ;
  582. ; Added this nifty comment block. ;
  583. ;-----------------------------------------------------------------------;
  584. assumes ds,nothing
  585. assumes es,nothing
  586. cProc SegLoad,<NEAR,PUBLIC>,<si,di>
  587. parmD pseginfo
  588. parmW segno
  589. parmW psegsrc
  590. parmW isfh
  591. localW hseg
  592. localW pseg
  593. localW psegdest
  594. localD prleinfo
  595. localW retry
  596. localW segoffset
  597. localW pleaseNoLock ;1 if segment is 64K
  598. localW allocTwice ;if first alloc fails, FreeTheWorld
  599. ifdef WOW_x86
  600. localD rover_2
  601. endif
  602. cBegin
  603. mov retry,1
  604. mov segoffset, 0
  605. mov allocTwice, 1
  606. les si,pseginfo
  607. mov ax,es:[si].ns_handle
  608. mov hseg,ax
  609. Handle_To_Sel al ; in case we don't lock
  610. mov pleaseNoLock, 1
  611. test es:[si].ns_flags, NSHUGESEG
  612. jnz dont_touch ;big segs are always locked and present
  613. mov pleaseNoLock, 0
  614. push es
  615. cCall MyLock,<ax>
  616. pop es
  617. or ax,ax
  618. jz try_alloc ; wish I could "jnz saalloced"
  619. dont_touch:
  620. jmps saalloced
  621. try_alloc:
  622. push es
  623. xor ax,ax
  624. mov bx, es:[si].ns_minalloc
  625. xor dx, dx
  626. cmp bx, 1
  627. adc dx, dx
  628. add bx, 2 ; We may have a 1 byte entry point at the
  629. adc dx, 0 ; very end of a segment. PatchCodeHandle
  630. ; will GP trying to decipher the prolog.
  631. ; Allow room to read relocation word
  632. cCall IGlobalReAlloc,<hseg,dx,bx,ax>
  633. pop es
  634. cmp hseg,ax
  635. jz sarealloced
  636. saerr2:
  637. test es:[si].ns_flags,NSDISCARD
  638. jz dont_scream
  639. push es
  640. cCall DiscardTheWorld ; Maybe if we try again
  641. pop es
  642. dec allocTwice
  643. jz try_alloc
  644. krDebugOut DEB_ERROR, "Out of mem loading seg %es2"
  645. dont_scream:
  646. jmp saerr1
  647. sarealloced: ; ax == handle
  648. Handle_To_Sel al
  649. cmp pleaseNoLock, 0
  650. jnz saalloced
  651. push es
  652. cCall MyLock,<hseg>
  653. pop es
  654. or ax,ax
  655. jz saerr2
  656. saalloced:
  657. mov pseg,ax
  658. mov psegdest,ax
  659. sareread:
  660. push es
  661. push si
  662. push ds ; We are going to trash this
  663. cld
  664. cmp es:[si].ns_sector,0 ; if sector == 0, then just init
  665. jnz sa_read_from_disk ; segment to all 0's
  666. ; mov cx, es:[si].ns_minalloc ; convert minalloc == 0 to 64K
  667. GETSEGLEN pseg
  668. mov cx, ax
  669. ifdef WOW_x86 ;
  670. .386
  671. ;; WOW we can use the magic flat selector 23h to write to any segment
  672. ;; This saves us calling get_rover_2 which makes an NT system call to set
  673. ;; a temp selector
  674. cCall get_physical_address,<pseg>
  675. shl edx,16
  676. mov dx,ax
  677. mov ax,FLAT_SEL
  678. mov es,ax
  679. xor eax, eax
  680. mov edi,edx ; es:edi -> pseg:0
  681. cmp cx, 1 ; Need to handle case where CX == 0
  682. mov dx, cx
  683. rcr cx, 1
  684. shr cx, 1
  685. movzx ecx,cx
  686. rep stos dword ptr [edi]
  687. mov cx, dx
  688. and cx, 3
  689. rep stos byte ptr [edi]
  690. jmp sa_after_read
  691. else ; 286
  692. cmp cx, 1 ; set CF if 0000
  693. rcr cx, 1 ; this sets CF for odd byte of size
  694. xor ax, ax
  695. xor di, di
  696. mov es, pseg ; start at pseg:0000
  697. call get_rover_2
  698. rep stosw
  699. adc cx, cx
  700. rep stosb ; this case now handled
  701. jmp sa_after_read
  702. endif;
  703. sa_read_from_disk:
  704. mov di,es:[si].ns_cbseg ; #bytes in segment to read
  705. ; If source segment address given then copy segment contents
  706. mov bx,psegsrc ; Get source handle
  707. cmp isfh,bx ; Is source a file handle?
  708. je sa_read_file ; Yes, go read segment from file
  709. ; We are reading from preload buffer, bx == src seg address, di == len
  710. push di ; No, set up for fast copy
  711. mov OFF_prleinfo,di
  712. mov SEG_prleinfo,bx
  713. pop cx
  714. mov ds,bx
  715. ifdef WOW_x86 ;
  716. .386
  717. ;; For WOW on NT we don't want to set the selector unesssarily
  718. cCall get_physical_address,<pseg>
  719. shl edx,16
  720. mov dx,ax
  721. mov rover_2,edx
  722. mov ax,FLAT_SEL
  723. mov es,ax
  724. mov edi,edx ; es:edi -> pseg:0
  725. xor esi,esi
  726. cmp cx, 1 ; set carry if 0 for big/huge segs
  727. mov ax, cx
  728. rcr cx, 1
  729. shr cx, 1
  730. movzx ecx,cx
  731. rep movs dword ptr [edi], dword ptr [esi]
  732. mov cx, ax
  733. and cx, 3
  734. rep movs byte ptr [edi], dword ptr [esi]
  735. sub edi,edx ; make di correct for rest of code
  736. else
  737. mov es,pseg ; Writing to pseg
  738. call get_rover_2
  739. xor si,si
  740. xor di,di
  741. ; need to handle case where seg size is 64K (cx == 0)
  742. cmp cx, 1 ; set carry if 0 for big/huge segs
  743. .386
  744. mov ax, cx
  745. rcr cx, 1
  746. shr cx, 1
  747. rep movsd
  748. mov cx, ax
  749. and cx, 3
  750. rep movsb
  751. .286
  752. endif; WOW_x86
  753. ; we have now read 'cbseg' bytes from preload buffer, di == cbseg
  754. jmp sa_zero_fill_rest
  755. saerr1:
  756. xor ax,ax
  757. jmp sax
  758. sa_read_file:
  759. ; read segment contents from disk file, bx == file handle
  760. ; ax = disk file sector
  761. if 0 ;KDEBUG
  762. push ax
  763. push ds
  764. SetKernelDS
  765. cmp fPreloadSeg, 0
  766. jne SHORT SkipDebugTrace
  767. mov ax, segno
  768. krDebugOut <DEB_TRACE or DEB_krLoadSeg>, "%ES0: reading segment #ax"
  769. SkipDebugTrace:
  770. pop ds
  771. UnSetKernelDS
  772. pop ax
  773. endif
  774. ; Get offset to data portion of segment in DX:AX
  775. mov ax, es:[si].ns_sector
  776. xor dx,dx
  777. mov cx,es:[ne_align]
  778. sa4a:
  779. shl ax,1
  780. adc dx, dx
  781. loop sa4a ; DX:AX = file offset to segment
  782. mov cx,dx ; Seek to beginning of segment data
  783. mov dx,ax
  784. mov ax,4200h ; lseek(bx, sector << align, SEEK_SET)
  785. DOSCALL
  786. jc saerr
  787. mov cx,di ; Get #bytes to read
  788. test es:[si].ns_flags,NSRELOC
  789. jz no_read_extra_word
  790. add cx, 2 ; Relocation word
  791. no_read_extra_word:
  792. mov ds,pseg ; Read segment from file
  793. xor dx,dx
  794. mov ah,3Fh
  795. test es:[si].ns_flags,NSITER
  796. jz @F
  797. call iterated_data_seg
  798. jmps sa_iter_done
  799. @@:
  800. or cx, cx ; if cx == 0 at this point, it is 64K
  801. jnz not_huge_read
  802. cmp es:[si].ns_minalloc,0 ; If minalloc isn't zero too, then the
  803. jnz not_huge_read ; segment is too small. Case should't
  804. ; happen but does for dbwindow, mimic Win 3.0.
  805. mov cx, 8000h
  806. DOSCALL ; read first 32K from disk
  807. jc saerr
  808. add dx, cx ; update destination address
  809. mov ah, 3fh ; restore AX (doscall trashes it)
  810. DOSCALL ; read second 32K
  811. jc saerr
  812. cmp ax, cx
  813. jnz saerr
  814. jmp short sa_zero_fill_rest
  815. not_huge_read:
  816. DOSCALL
  817. sa_iter_done:
  818. jc saerr ; Continue if no errors
  819. cmp ax,cx ; Read ok, did we get what we asked for?
  820. jne saerr ; No, fail
  821. test es:[si].ns_flags,NSRELOC ; Relocation records?
  822. jz sa_zero_fill_rest ; No, continue
  823. mov ax, ds:[di] ; Extra word was read here
  824. mov OFF_prleinfo, ax
  825. jmps sa_zero_fill_rest
  826. saerr:
  827. pop ds
  828. pop si
  829. pop es
  830. mov ax, -1 ; File error
  831. jmp sax
  832. sa_zero_fill_rest: ; di == bytes written so far
  833. GETSEGLEN pseg ; seg len to ax, 0 == 64K
  834. sub ax,di ; Any uninitialized portion?
  835. jz sa_after_read ; No, continue
  836. ifdef WOW_x86;
  837. .386
  838. ;; WOW we don't want to call NT to set the selector
  839. push ax
  840. cCall get_physical_address,<psegdest>
  841. shl edx,16
  842. mov dx,ax
  843. mov ax,FLAT_SEL
  844. mov es,ax
  845. and edi,0000ffffh
  846. add edi,edx ; es:edi -> pseg:0
  847. pop cx
  848. push edx
  849. xor eax,eax
  850. cld
  851. mov dx,cx
  852. shr cx, 2
  853. movzx ecx,cx
  854. rep stos dword ptr [edi]
  855. mov cx, dx
  856. and cx, 3
  857. rep stos byte ptr [edi]
  858. pop edx
  859. sub edi,edx
  860. else
  861. mov es,psegdest ; Yes, set it to zero
  862. call get_rover_2
  863. mov cx,ax
  864. xor ax,ax
  865. cld
  866. shr cx, 1
  867. rep stosw
  868. adc cx, cx
  869. rep stosb
  870. endif
  871. sa_after_read:
  872. les si, pseginfo
  873. if LDCHKSUM
  874. mov ds,psegdest
  875. xor si,si
  876. mov cx,di
  877. shr cx,1
  878. xor dx,dx
  879. cld
  880. sa5b:
  881. lodsw
  882. xor dx,ax
  883. loop sa5b
  884. endif
  885. cmp pleaseNoLock, 0
  886. jnz dont_patch
  887. push dx
  888. cCall <far ptr PatchCodeHandle>,<hseg>
  889. pop dx
  890. dont_patch:
  891. pop ds ; Restore DS
  892. pop si ; segment info pointer
  893. pop es
  894. mov ax,es:[si].ns_flags ; Are we loading a code segment?
  895. and ax,NSDATA
  896. .errnz NSCODE
  897. jnz sa9
  898. ; Here when loading a code segment
  899. if LDCHKSUM
  900. mov cx,segno
  901. dec cx
  902. shl cx,1
  903. shl cx,1
  904. mov di,es:[ne_psegcsum]
  905. add di,cx
  906. mov cx,dx
  907. xchg es:[di],cx
  908. jcxz sa6a0
  909. cmp cx,dx
  910. je sa6a0
  911. dec retry
  912. jl sa6a1
  913. public badsegread
  914. badsegread:
  915. mov ah,0Dh ; Disk Reset
  916. DOSCALL
  917. jmp sareread
  918. sa6a1:
  919. krDebugOut DEB_ERROR, "Segment contents invalid %es2"
  920. xor ax,ax
  921. jmps sax
  922. sa6a0:
  923. mov word ptr es:[di+2],0
  924. endif
  925. sa9:
  926. mov dx,SEG_prleinfo
  927. mov cx,OFF_prleinfo
  928. mov bx,hseg
  929. mov ax,pseg
  930. sax: or ax,ax
  931. cEnd
  932. .286
  933. ;-----------------------------------------------------------------------;
  934. ; iterated_data_seg
  935. ;
  936. ; This expands out iterated data segments (specifically for the
  937. ; OS/2 m.exe). Due to the late date this is being sleazed in
  938. ; instead of being done right. To be done right, the read would
  939. ; go into the last part of the present block, and expanded in place,
  940. ; the stack used for the next record count because the last record
  941. ; never fits.
  942. ;
  943. ; Entry:
  944. ; CX = number of bytes to read
  945. ; DS:DX = place to put them
  946. ; DS:DI = place where #relocs will magically appear
  947. ; ES:SI = module exe header:seg info
  948. ;
  949. ; Returns:
  950. ; CF = 1
  951. ; DS:DI = updated magic place where #relocs will magically appear
  952. ;
  953. ; Error Return:
  954. ; CX = 0
  955. ;
  956. ; Registers Destroyed:
  957. ;
  958. ; History:
  959. ; Sun 28-Jan-1990 12:25:02 -by- David N. Weise [davidw]
  960. ; Wrote it!
  961. ;-----------------------------------------------------------------------;
  962. assumes ds,nothing
  963. assumes es,nothing
  964. cProc iterated_data_seg,<PUBLIC,NEAR>,<bx,dx,si,ds,es>
  965. localW temp_buf
  966. localW freloc
  967. cBegin
  968. ; deal with that extra relocation word!
  969. xor ax,ax
  970. test es:[si].ns_flags,NSRELOC ; Relocation records?
  971. jz @F
  972. inc ax
  973. @@: mov freloc,ax
  974. ; first get a temp buffer
  975. push bx
  976. push cx
  977. cCall IGlobalAlloc,<0,0,cx>
  978. mov temp_buf,ax
  979. pop cx
  980. pop bx
  981. or ax,ax
  982. stc ; assume failure
  983. jz ids_exit
  984. push dx
  985. push ds
  986. ; read into the temp buffer
  987. mov ds,ax
  988. xor dx,dx
  989. mov ah,3Fh
  990. DOSCALL
  991. pop ds
  992. pop dx
  993. jc ids_exit1
  994. cmp ax,cx
  995. jnz ids_exit1
  996. ; expand the buffer, yes we should special case strings of length 1
  997. cmp freloc,0 ; was an extra word read?
  998. jz @F
  999. sub cx,2
  1000. @@: mov dx,cx
  1001. smov es,ds
  1002. xor di,di
  1003. mov ds,temp_buf
  1004. xor si,si
  1005. cld
  1006. ids_next_group:
  1007. lodsw ; get the # interations
  1008. mov cx,ax
  1009. lodsw ; get the # bytes
  1010. @@: push cx
  1011. push si
  1012. mov cx,ax
  1013. rep movsb
  1014. pop si
  1015. pop cx
  1016. loop @B
  1017. add si,ax ; get past group
  1018. cmp si,dx
  1019. jb ids_next_group
  1020. ; data segment now processed, deal with reloc word
  1021. cmp freloc,0 ; was an extra word read?
  1022. jz @F
  1023. movsw
  1024. sub di,2
  1025. add dx,2
  1026. @@: mov ax,dx
  1027. mov cx,dx
  1028. clc
  1029. ids_exit1:
  1030. pushf ; preserve the carry flag
  1031. push ax
  1032. push cx
  1033. smov ds,0
  1034. cCall IGlobalFree,<temp_buf>
  1035. pop cx
  1036. pop ax
  1037. popf
  1038. ids_exit:
  1039. cEnd
  1040. ;-----------------------------------------------------------------------;
  1041. ; PatchCodeHandle ;
  1042. ; ;
  1043. ; Patches the prologs of the procedures in the given code segment. ;
  1044. ; ;
  1045. ; Arguments: ;
  1046. ; parmW hseg ;
  1047. ; ;
  1048. ; Returns: ;
  1049. ; AX = hseg ;
  1050. ; DX = pseg ;
  1051. ; ;
  1052. ; Error Returns: ;
  1053. ; ;
  1054. ; Registers Preserved: ;
  1055. ; DI,SI,DS ;
  1056. ; ;
  1057. ; Registers Destroyed: ;
  1058. ; BX,CX,ES ;
  1059. ; ;
  1060. ; Calls: ;
  1061. ; MyLock ;
  1062. ; ;
  1063. ; History: ;
  1064. ; ;
  1065. ; Sun 17-Sep-1989 10:45:24 -by- David N. Weise [davidw] ;
  1066. ; Added support for symdeb to understand segments in himem. ;
  1067. ; ;
  1068. ; Tue Oct 27, 1987 06:19:12p -by- David N. Weise [davidw] ;
  1069. ; Added this nifty comment block. ;
  1070. ;-----------------------------------------------------------------------;
  1071. assumes ds,nothing
  1072. assumes es,nothing
  1073. cProc PatchCodeHandle,<PUBLIC,FAR>,<si,di>
  1074. parmW hseg
  1075. localW pseg
  1076. localW hexe
  1077. localW segno
  1078. localW segoffset
  1079. ifdef WOW_x86
  1080. .386
  1081. localD rover_2
  1082. endif
  1083. cBegin
  1084. SetKernelDS
  1085. cCall MyLock,<hseg>
  1086. mov pseg,ax ; Save physical addresss
  1087. or ax,ax ; All done if discarded
  1088. jz pcsDone1
  1089. xor si,si
  1090. mov segoffset, si
  1091. push ax
  1092. cCall GetOwner,<pseg>
  1093. mov es, ax
  1094. pop ax
  1095. cmp es:[si].ne_magic,NEMAGIC
  1096. if KDEBUG
  1097. jz good_boy
  1098. bad_boy:
  1099. krDebugOut DEB_ERROR "PatchCodeHandle, owner not NewExe %es2"
  1100. jmps pcsDone1
  1101. good_boy:
  1102. endif
  1103. jne pcsDone1
  1104. mov hexe,es
  1105. mov cx,es:[si].ne_cseg ; We need si to point to entry
  1106. mov si,es:[si].ne_segtab ; anyway so do it the slow way
  1107. pcsLoop:
  1108. cmp es:[si].ns_handle,dx ; Scan table for handle
  1109. je pcsFound
  1110. add si,SIZE NEW_SEG1
  1111. loop pcsLoop
  1112. pcsDone1:
  1113. jmp pcsDone
  1114. pcsExit1:
  1115. jmp pcsExit
  1116. pcsFound:
  1117. sub cx,es:[ne_cseg] ; Compute segment# from remainder
  1118. neg cx ; of loop count
  1119. inc cx ; 1-based segment#
  1120. mov segno,cx
  1121. test es:[si].ns_flags,NSDATA
  1122. jnz pcsExit1
  1123. .errnz NSCODE
  1124. push si
  1125. mov di,es:[ne_pautodata]
  1126. or di,di
  1127. jz sa6a
  1128. cCall MyLock,<es:[di].ns_handle>
  1129. mov di,ax
  1130. sa6a: ; DI:0 points to data segment (or 0)
  1131. ifdef WOW_x86
  1132. ;; For WOW we use the NT Magic data selector, since all 16 bit code is DATA
  1133. cCall get_physical_address,<pseg>
  1134. assumes es,nothing
  1135. shl edx,16
  1136. mov dx,ax ; ES:EDX -> pseg:0
  1137. mov rover_2,edx
  1138. mov ax,FLAT_SEL
  1139. mov es,ax
  1140. else
  1141. mov es,pseg ; ES:0 points to code segment
  1142. call get_rover_2
  1143. endif
  1144. mov ds,hexe ; DS:SI points to entry table
  1145. assumes ds,nothing
  1146. mov si,ds:[ne_enttab]
  1147. cld
  1148. or di, di ; Anything to do?
  1149. jz sa6x
  1150. sa6b:
  1151. lods word ptr ds:[si]
  1152. mov dx, ax
  1153. lods word ptr ds:[si]
  1154. sub ax, dx ; Get # entries in this block
  1155. or ax,ax
  1156. jz sa6x ; Done if zero
  1157. push word ptr ds:[si] ; Next block
  1158. add si, 2 ; Skip Next
  1159. mov cx,ax
  1160. sa6c:
  1161. mov al,ds:[si].pentsegno ; Get segment# from int instruction
  1162. cmp byte ptr segno,al ; Does this moveable segment match ES?
  1163. jne sa6e ; No, advance to next entry
  1164. ifdef WOW_x86
  1165. movzx ebx, word ptr ds:[si].pentoffset ; Get entry point offset
  1166. add ebx,rover_2
  1167. mov al, ds:[si].pentflags ; Get entry point flags
  1168. cmp byte ptr es:[ebx+2],90h ; Yes, followed by nop?
  1169. jne sa6e ; No, can;t patch prolog then
  1170. cmp word ptr es:[ebx],0581Eh ; Is it a push ds, pop ax?
  1171. jne @F ; Yes, take care of prolog
  1172. mov word ptr es:[ebx],0D88Ch
  1173. jmps sa6d1
  1174. @@:
  1175. cmp word ptr es:[ebx],0D88Ch ; Is it a mov ax,ds?
  1176. jne sa6e ; No, can't patch prolog then
  1177. sa6d1:
  1178. test al,ENT_DATA ; Valid prolog. shared data?
  1179. jnz sa6d2 ; Yes, patch mov ax,DGROUP into prolog
  1180. test byte ptr ds:[ne_flags],NEINST ; No, multiple instances?
  1181. jz sa6e ; No, do nothing
  1182. test al,ENT_PUBLIC ; Public entry point?
  1183. jz sa6e ; No, do nothing
  1184. mov word ptr es:[ebx],09090h ; Yes, set nop, nop in prolog
  1185. jmps sa6e
  1186. sa6d2:
  1187. mov byte ptr es:[ebx],0B8h ; Set mov ax,
  1188. mov es:[ebx+1],di ; DGROUP
  1189. else ; NOT WOW_x86
  1190. mov bx, ds:[si].pentoffset ; Get entry point offset
  1191. mov al, ds:[si].pentflags ; Get entry point flags
  1192. cmp byte ptr es:[bx+2],90h ; Yes, followed by nop?
  1193. jne sa6e ; No, can;t patch prolog then
  1194. cmp word ptr es:[bx],0581Eh ; Is it a push ds, pop ax?
  1195. jne @F ; Yes, take care of prolog
  1196. mov word ptr es:[bx],0D88Ch
  1197. jmps sa6d1
  1198. @@:
  1199. cmp word ptr es:[bx],0D88Ch ; Is it a mov ax,ds?
  1200. jne sa6e ; No, can't patch prolog then
  1201. sa6d1:
  1202. test al,ENT_DATA ; Valid prolog. shared data?
  1203. jnz sa6d2 ; Yes, patch mov ax,DGROUP into prolog
  1204. test byte ptr ds:[ne_flags],NEINST ; No, multiple instances?
  1205. jz sa6e ; No, do nothing
  1206. test al,ENT_PUBLIC ; Public entry point?
  1207. jz sa6e ; No, do nothing
  1208. mov word ptr es:[bx],09090h ; Yes, set nop, nop in prolog
  1209. jmps sa6e
  1210. sa6d2:
  1211. mov byte ptr es:[bx],0B8h ; Set mov ax,
  1212. mov es:[bx+1],di ; DGROUP
  1213. endif; WOW_x86
  1214. sa6e:
  1215. add si,SIZE PENT ; Advance to next entry in
  1216. loop sa6c ; this block
  1217. pop si
  1218. or si, si
  1219. jnz sa6b
  1220. sa6x:
  1221. mov es,hexe
  1222. pop si
  1223. pcsExit:
  1224. or byte ptr es:[si].ns_flags,NSLOADED ; Mark segment as loaded
  1225. ;;;if SDEBUG ; Tell debugger about new segment
  1226. ;;; mov bx,es:[ne_restab]
  1227. ;;; inc bx
  1228. ;;; mov dx,es:[si].ns_flags
  1229. ;;; mov ax,segoffset ; tell symdeb how to fixup symbols
  1230. ;;; test dx,NSDATA ; test to pass NSKCACHED too
  1231. ;;; jz sa8
  1232. ;;; test byte ptr es:[ne_flags],NEINST
  1233. ;;; jz sa8
  1234. ;;; mov ax,es:[ne_usage]
  1235. ;;; dec ax
  1236. ;;;sa8:
  1237. ;;; mov cx,segno
  1238. ;;; dec cx
  1239. ;;; cCall DebugDefineSegment,<esbx,cx,pseg,ax,dx>
  1240. ;;;endif
  1241. pcsDone:
  1242. mov ax,hseg
  1243. mov dx,pseg
  1244. cEnd
  1245. sEnd CODE
  1246. externFP FarAllocSeg
  1247. externFP FarMyAlloc
  1248. externFP FarMyAllocLinear
  1249. externFP FarMyFree
  1250. externFP FarSetOwner
  1251. sBegin NRESCODE
  1252. assumes CS,NRESCODE
  1253. assumes DS,NOTHING
  1254. assumes ES,NOTHING
  1255. externNP MapDStoDATA
  1256. externA __AHINCR
  1257. ;-----------------------------------------------------------------------;
  1258. ; AllocAllSegs ;
  1259. ; ;
  1260. ; "Allocates" for all segments of the module being loaded and stores ;
  1261. ; the addresses in the segment table. By allocate we mean: ;
  1262. ; ;
  1263. ; AUTOMATIC DATA gets space, but not yet loaded, ;
  1264. ; PRELOAD FIXED get global mem allocated , but not yet loaded, ;
  1265. ; MOVEABLE get a handle for later use, ;
  1266. ; FIXED get nothing. ;
  1267. ; ;
  1268. ; If this is not the first instance, then just allocate space for ;
  1269. ; the new instance of the automatic data segment. ;
  1270. ; ;
  1271. ; Arguments: ;
  1272. ; parmW hexe ;
  1273. ; ;
  1274. ; Returns: ;
  1275. ; ;
  1276. ; Error Returns: ;
  1277. ; AX =-1 not enough memory ;
  1278. ; ;
  1279. ; Registers Preserved: ;
  1280. ; ;
  1281. ; Registers Destroyed: ;
  1282. ; ;
  1283. ; Calls: ;
  1284. ; FarAllocSeg ;
  1285. ; FarMyAlloc ;
  1286. ; FarMyFree ;
  1287. ; ;
  1288. ; History: ;
  1289. ; ;
  1290. ; Tue Feb 24, 1987 01:04:12p -by- David N. Weise [davidw] ;
  1291. ; Added this nifty comment block. ;
  1292. ;-----------------------------------------------------------------------;
  1293. cProc AllocAllSegs,<NEAR,PUBLIC>,<si,di,ds>
  1294. parmW hexe
  1295. localW cSegs
  1296. localD hugeLen ; cum length of huge segment
  1297. localW hugeIndex ; index of first segment of huge
  1298. localW hugeOffs ; offset of first segment desc of huge
  1299. localW hugeCnt ; segments making up huge seg
  1300. localW hugeFlags ; flags of huge segment (needed?)
  1301. cBegin
  1302. call MapDStoDATA
  1303. ReSetKernelDS
  1304. mov es,hexe
  1305. mov si,es:[ne_segtab]
  1306. xor di,di
  1307. mov cSegs,di
  1308. inc di
  1309. cmp es:[ne_usage],di
  1310. je paloop
  1311. mov si,es:[ne_pautodata]
  1312. and byte ptr es:[si].ns_flags,not NSALLOCED+NSLOADED
  1313. mov di,es:[si].ns_handle
  1314. cCall FarAllocSeg,<essi>
  1315. or ax,ax
  1316. jz aa_nomem
  1317. inc cSegs
  1318. outahere:
  1319. jmp pagood
  1320. aa_nomem:
  1321. mov es,hexe
  1322. or byte ptr es:[si].ns_flags,NSALLOCED+NSLOADED
  1323. mov es:[si].ns_handle,di
  1324. jmp pafail3
  1325. paloop:
  1326. cmp di,es:[ne_cseg]
  1327. jbe more_to_go
  1328. jmp pagood
  1329. more_to_go:
  1330. mov bx,es:[si].ns_flags
  1331. test bl,NSPRELOAD ; Are we preloading?
  1332. jz not_preload
  1333. test bl,NSDATA ; Preload data although moveable
  1334. jnz paalloc
  1335. test bl,NSMOVE ; Fixed segment?
  1336. jz paalloc ; Yes, allocate segment
  1337. not_preload:
  1338. test bl,NSALLOCED ; Already allocated?
  1339. jnz panext ; Yes, then nothing to do
  1340. test bl,NSMOVE ; Fixed segment?
  1341. jz panext ; Yes, then nothing to do
  1342. xor cx,cx ; No, allocate zero length
  1343. push es ; object so that we guarantee
  1344. cCall FarMyAlloc,<bx,cx,cx> ; we will have a handle.
  1345. pop es
  1346. or dx,dx ; Fail if we cant get a handle
  1347. jz pafail
  1348. mov es:[si].ns_handle,dx ; Handle into seg table
  1349. and byte ptr es:[si].ns_flags,not NSLOADED
  1350. or byte ptr es:[si].ns_flags,NSALLOCED
  1351. mov bx,dx ; put handle into base register
  1352. call set_discarded_sel_owner
  1353. jmps panext
  1354. paalloc:
  1355. cmp es:[si].ns_minalloc, 0
  1356. jnz paalloc_fer_shure
  1357. jmps PAHugeAlloc
  1358. paalloc_fer_shure:
  1359. cCall FarAllocSeg,<essi>
  1360. or ax,ax
  1361. jz pafail
  1362. inc cSegs
  1363. panext:
  1364. add si,size NEW_SEG1
  1365. inc di
  1366. jmp paloop
  1367. ; only gets here if not enough memory, free up all previous segments
  1368. pafail:
  1369. mov si,es:[ne_segtab]
  1370. mov cx,es:[ne_cseg]
  1371. pafail1:
  1372. push cx
  1373. mov cx,es:[si].ns_handle
  1374. jcxz pafail2
  1375. push es
  1376. ;Need to handle freeing huge segments!!!
  1377. cCall FarMyFree,<cx>
  1378. pop es
  1379. mov es:[si].ns_handle, 0 ; Necessary for EntProcAddress
  1380. pafail2:
  1381. and byte ptr es:[si].ns_flags,not (NSALLOCED+NSLOADED)
  1382. add si,size NEW_SEG1
  1383. pop cx
  1384. loop pafail1
  1385. pafail3:
  1386. mov cSegs,-1
  1387. jmp pagood
  1388. PAHugeAlloc:
  1389. ; at this point, es:si -> current seg record
  1390. ; di is segment index (range from 1 to es:[ne_cseg])
  1391. mov off_hugeLen, 0
  1392. mov seg_hugeLen, 0 ; init length to 0K
  1393. mov hugeOffs, si
  1394. mov hugeCnt, 1
  1395. mov ax, es:[si].ns_flags
  1396. or ax, NSHUGESEG
  1397. mov hugeFlags, ax
  1398. PAHugeLoop:
  1399. mov ax, es:[si].ns_minalloc ; add current segment to group
  1400. cmp ax, 1
  1401. sbb dx, dx
  1402. neg dx
  1403. add off_hugeLen, ax
  1404. adc seg_hugeLen, dx
  1405. or es:[si].ns_flags, NSHUGESEG
  1406. cmp es:[si].ns_minalloc, 0 ;
  1407. jnz PAHugeEndLoop
  1408. cmp di, es:[ne_cseg]
  1409. jae PAHugeEndLoop
  1410. mov ax, si
  1411. add ax, size NEW_SEG1
  1412. cmp ax, es:[ne_pautodata]
  1413. jz PAHugeEndLoop
  1414. mov ax, hugeFlags ; do flags have to be identical?
  1415. cmp ax, es:[si].ns_flags
  1416. jnz PAHugeEndLoop
  1417. inc hugeCnt
  1418. inc di
  1419. add si, size NEW_SEG1
  1420. jmp PAHugeLoop
  1421. PAHugeEndLoop:
  1422. inc di
  1423. push es
  1424. or hugeFlags, NSMOVE
  1425. cCall FarMyAllocLinear, <hugeFlags, hugeLen>
  1426. pop es
  1427. or ax, ax ; check for error
  1428. jnz Not_pafail
  1429. jmp pafail
  1430. Not_pafail:
  1431. mov si, hugeOffs ; fix up segment(s)
  1432. and es:[si].ns_flags, NOT NSHUGESEG
  1433. PAHugeSegLoop:
  1434. mov es:[si].ns_handle, dx
  1435. and byte ptr es:[si].ns_flags, not NSLOADED
  1436. or byte ptr es:[si].ns_flags, NSALLOCED
  1437. cCall FarSetOwner, <ax, es>
  1438. add si, size NEW_SEG1
  1439. add dx, __AHINCR
  1440. dec hugeCnt
  1441. jnz PAHugeSegLoop
  1442. ; continue with rest of allocations
  1443. jmp paloop
  1444. pagood:
  1445. mov ax,cSegs
  1446. cEnd
  1447. sEnd NRESCODE
  1448. end