Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1970 lines
43 KiB

  1. page ,132
  2. title TASK - task create/destroy procedures
  3. .xlist
  4. include kernel.inc
  5. include tdb.inc
  6. include pdb.inc
  7. include eems.inc
  8. include newexe.inc
  9. include dbgsvc.inc
  10. include bop.inc
  11. .list
  12. outd macro msg,n
  13. %out msg n
  14. endm
  15. if2
  16. ; outd <TDBsize =>,%TDBsize
  17. endif
  18. externW pStackBot
  19. externW pStackMin
  20. externW pStackTop
  21. if ROM
  22. externFP FarIsROMObject
  23. endif
  24. externFP SafeCall
  25. externFP BuildPDB
  26. externFP LockSegment
  27. externFP UnlockSegment
  28. ;externFP Yield
  29. externFP LocalInit
  30. externFP GlobalAlloc
  31. externFP GlobalFree
  32. ;externFP GlobalLock
  33. externFP GlobalUnLock
  34. externFP GlobalCompact
  35. externFP IGlobalHandle
  36. externFP GlobalLRUOldest
  37. externFP AllocDStoCSAlias
  38. ;;;externFP FarMyLock
  39. externFP FarSetOwner
  40. externFP default_sig_handler
  41. externFP CVW_Hack
  42. externFP GlobalDOSAlloc
  43. externFP GlobalDOSFree
  44. externFP AllocSelector
  45. externFP LongPtrAdd
  46. externFP MyFarDebugCall
  47. externFP Int21Handler
  48. if PMODE32
  49. externFP far_get_arena_pointer32
  50. externFP FarAssociateSelector32
  51. externFP KRebootInit
  52. else
  53. externFP far_get_arena_pointer
  54. externFP FarAssociateSelector
  55. endif
  56. if KDEBUG
  57. externFP SetupAllocBreak
  58. endif
  59. ifdef WOW
  60. externFP SetAppCompatFlags
  61. externFP WowReserveHtask
  62. externFP FreeSelector
  63. externFP WowPassEnvironment
  64. externFP ExitCall
  65. endif
  66. DataBegin
  67. ;externB fEMM
  68. externB fBooting
  69. externB kernel_flags
  70. externB num_tasks
  71. ;externW hexehead
  72. externW pGlobalHeap
  73. externW curTDB
  74. externW loadTDB
  75. externW headTDB
  76. externW headPDB
  77. externW topPDB
  78. externW cur_DOS_PDB
  79. externW Win_PDB
  80. ;if PMODE32
  81. ;externW ArenaSel
  82. ;endif
  83. externW MyCSAlias
  84. externD pUserInitDone
  85. externD ptrace_app_entry
  86. externD ptrace_DLL_entry
  87. externD pSignalProc
  88. if KDEBUG
  89. globalW allocTask,0
  90. globalD allocCount,0
  91. globalD allocBreak,0
  92. globalB allocModName,0,8
  93. endif ;KDEBUG
  94. if ROM
  95. externD prevInt00proc
  96. endif
  97. ifdef WOW
  98. externD FastBop
  99. externW DebugWOW
  100. endif
  101. DataEnd
  102. sBegin CODE
  103. assumes CS,CODE
  104. assumes DS,NOTHING
  105. assumes ES,NOTHING
  106. ife ROM
  107. externD prevInt00proc
  108. endif
  109. externNP SaveState
  110. externNP UnlinkObject
  111. externNP genter
  112. externNP gleave
  113. nullcomline DB 0,0Dh
  114. ;-----------------------------------------------------------------------;
  115. ; GetCurrentTask ;
  116. ; ;
  117. ; Returns the current task. ;
  118. ; ;
  119. ; Arguments: ;
  120. ; none ;
  121. ; ;
  122. ; Returns: ;
  123. ; AX = curTDB ;
  124. ; DX = headTDB ;
  125. ; ;
  126. ; Error Returns: ;
  127. ; ;
  128. ; Registers Preserved: ;
  129. ; all ;
  130. ; ;
  131. ; Registers Destroyed: ;
  132. ; ;
  133. ; Calls: ;
  134. ; nothing ;
  135. ; ;
  136. ; History: ;
  137. ; ;
  138. ; Sun Feb 01, 1987 07:45:40p -by- David N. Weise [davidw] ;
  139. ; Added this nifty comment block. ;
  140. ;-----------------------------------------------------------------------;
  141. assumes ds,nothing
  142. assumes es,nothing
  143. cProc GetCurrentTask,<PUBLIC,FAR>
  144. cBegin nogen
  145. push es
  146. SetKernelDS ES
  147. mov ax,curTDB
  148. mov dx,headTDB
  149. ; mov bx,codeOffset headTDB
  150. ; mov cx,codeOffset curTDB
  151. pop es
  152. ret
  153. assumes es,nothing
  154. cEnd nogen
  155. ;-----------------------------------------------------------------------;
  156. ; InsertTask ;
  157. ; ;
  158. ; Inserts a task into the task list. ;
  159. ; ;
  160. ; Arguments: ;
  161. ; parmW hTask ;
  162. ; ;
  163. ; Returns: ;
  164. ; ;
  165. ; Error Returns: ;
  166. ; ;
  167. ; Registers Preserved: ;
  168. ; CX,DX,DI,SI,DS ;
  169. ; ;
  170. ; Registers Destroyed: ;
  171. ; AX,BX,ES ;
  172. ; ;
  173. ; Calls: ;
  174. ; nothing ;
  175. ; ;
  176. ; History: ;
  177. ; ;
  178. ; Sun Feb 01, 1987 09:41:24p -by- David N. Weise [davidw] ;
  179. ; Added this nifty comment block. ;
  180. ;-----------------------------------------------------------------------;
  181. assumes ds,nothing
  182. assumes es,nothing
  183. cProc InsertTask,<PUBLIC,NEAR>,<ds>
  184. parmW hTask
  185. cBegin
  186. mov es,hTask ; get task handle
  187. SetKernelDS
  188. mov ax,headTDB ; get head of task list
  189. UnSetKernelDS
  190. or ax,ax ; anybody here?
  191. jz ins1 ; no, just do trivial case
  192. ins0: mov ds,ax ; point to head TDB
  193. mov bl,es:[TDB_priority] ; get insert priority
  194. cmp bl,ds:[TDB_priority] ; is it less than head task?
  195. jg ins2 ; no, insert elsewhere
  196. mov es:[TDB_next],ax
  197. ins1: SetKernelDS
  198. mov headTDB,es
  199. UnSetKernelDS
  200. jmps ins4
  201. ins2: mov ds,ax ; save segment of previous TDB
  202. mov ax,ds:[TDB_next] ; get segment of next tdb
  203. or ax,ax ; if zero, insert now
  204. jz ins3
  205. mov es,ax ; point to new TDB
  206. cmp bl,es:[TDB_priority]
  207. jg ins2
  208. ins3: mov es,hTask
  209. mov ds:[TDB_next],es
  210. mov es:[TDB_next],ax
  211. ins4:
  212. cEnd
  213. ;-----------------------------------------------------------------------;
  214. ; DeleteTask ;
  215. ; ;
  216. ; Deletes a task from the task list. ;
  217. ; ;
  218. ; Arguments: ;
  219. ; parmW hTask ;
  220. ; ;
  221. ; Returns: ;
  222. ; AX = hTask ;
  223. ; ;
  224. ; Error Returns: ;
  225. ; ;
  226. ; Registers Preserved: ;
  227. ; ;
  228. ; Registers Destroyed: ;
  229. ; ;
  230. ; Calls: ;
  231. ; UnlinkObject ;
  232. ; ;
  233. ; History: ;
  234. ; ;
  235. ; Sun Feb 01, 1987 09:41:24p -by- David N. Weise [davidw] ;
  236. ; Added this nifty comment block. ;
  237. ;-----------------------------------------------------------------------;
  238. assumes ds,nothing
  239. assumes es,nothing
  240. cProc DeleteTask,<PUBLIC,NEAR>
  241. parmW hTask
  242. cBegin
  243. mov es,hTask
  244. mov bx,dataOffset headTDB
  245. mov dx,TDB_next
  246. call UnlinkObject ; returns AX = hTask
  247. cEnd
  248. cProc FarCreateTask,<PUBLIC,FAR> ; Called from CreateTask
  249. ; parmW fPrev ; Calls several 'near' CODE funcs
  250. cBegin
  251. cCall SaveState,<ds>
  252. SetKernelDS es
  253. mov loadTDB,ds
  254. cCall InsertTask,<ds>
  255. clc
  256. cEnd
  257. if KDEBUG
  258. ;-----------------------------------------------------------------------
  259. ;
  260. ; CheckGAllocBreak
  261. ;
  262. ; Checks to see if the allocation break count has been reached.
  263. ; Returns CARRY SET if the allocation should fail, CLEAR otherwise.
  264. ; Increments the allocation count.
  265. ;
  266. ;-----------------------------------------------------------------------
  267. LabelNP <PUBLIC, CheckGAllocBreak>
  268. errn$ CheckLAllocBreak
  269. cProc CheckLAllocBreak,<PUBLIC,NEAR>,<DS,AX>
  270. cBegin
  271. SetKernelDS
  272. assumes ds,DATA
  273. mov ax,allocTask ; if allocTask != curTDB, exit.
  274. or ax,ax ; curTDB may be NULL during boot.
  275. jz cab_nofail
  276. cmp ax,curTDB
  277. jnz cab_nofail
  278. mov ax,word ptr allocBreak
  279. cmp ax,word ptr allocCount ; if allocBreak != allocCount
  280. jnz cab_increment ; inc allocCount
  281. mov ax,word ptr allocBreak+2
  282. cmp ax,word ptr allocCount+2
  283. jnz cab_increment
  284. or ax,word ptr allocBreak ; if allocBreak is 0L, just inc.
  285. jz cab_increment
  286. krDebugOut <DEB_ERROR>, "Alloc break: Failing allocation"
  287. stc ; return carry set
  288. jmp short cab_exit
  289. cab_increment:
  290. inc word ptr allocCount ; increment allocCount
  291. jnz cab_nofail
  292. inc word ptr allocCount+2
  293. cab_nofail:
  294. clc
  295. cab_exit:
  296. assumes ds,NOTHING
  297. cEnd
  298. endif ;KDEBUG
  299. sEnd CODE
  300. sBegin NRESCODE
  301. assumes CS,NRESCODE
  302. assumes DS,NOTHING
  303. assumes ES,NOTHING
  304. externNP MapDStoDATA
  305. externNP GetInstance
  306. externNP StartProcAddress
  307. ;-----------------------------------------------------------------------;
  308. ; CreateTask ;
  309. ; ;
  310. ; "Creates" a new task. It allocates the memory for the TDB+PDB struc, ;
  311. ; builds the PDB, constructs the TDB, initializes the EEMS memory ;
  312. ; arena, and sets the signature word in the TDB. TDB actually added ;
  313. ; to task queue by StartTask. ;
  314. ; ;
  315. ; Arguments: ;
  316. ; parmD pParmBlk ;
  317. ; parmW pExe ;
  318. ; parmW hPrev instance ;
  319. ; parmW fWOA ;
  320. ; ;
  321. ; Returns: ;
  322. ; AX = segment of TDB ;
  323. ; ;
  324. ; Error Returns: ;
  325. ; AX = 0 ;
  326. ; ;
  327. ; Registers Preserved: ;
  328. ; DI,SI,DS ;
  329. ; ;
  330. ; Registers Destroyed: ;
  331. ; ;
  332. ; Calls: ;
  333. ; ;
  334. ; History: ;
  335. ; ;
  336. ; Thu 04-Jan-1990 21:18:25 -by- David N. Weise [davidw] ;
  337. ; Added support for OS/2 apps. ;
  338. ; ;
  339. ; Mon 07-Aug-1989 23:28:15 -by- David N. Weise [davidw] ;
  340. ; Added support for long command lines to winoldap. ;
  341. ; ;
  342. ; Thu Apr 09, 1987 03:53:16p -by- David N. Weise [davidw] ;
  343. ; Added the initialization for EMS a while ago, recently added the ;
  344. ; switching of stacks to do it. ;
  345. ; ;
  346. ; Sun Feb 01, 1987 07:46:53p -by- David N. Weise [davidw] ;
  347. ; Added this nifty comment block. ;
  348. ;-----------------------------------------------------------------------;
  349. assumes ds,nothing
  350. assumes es,nothing
  351. cProc CreateTask,<PUBLIC,FAR>,<si,di>
  352. parmD pParmBlk
  353. parmW pExe
  354. ; parmW fPrev
  355. parmW fWOA
  356. localW env_seg
  357. localW comline_start
  358. cBegin
  359. call MapDStoDATA
  360. ReSetKernelDS
  361. cld
  362. xor si,si
  363. mov env_seg,si
  364. mov comline_start,si
  365. cmp si,pParmBlk.sel
  366. jz parm_block_considered
  367. cCall pass_environment,<pExe,pParmBlk>
  368. inc ax
  369. jnz @F
  370. jmp ats6
  371. @@: dec ax
  372. mov env_seg,ax
  373. mov comline_start,dx
  374. mov si,size PDB ; start with size of PDB
  375. cmp fWOA,0
  376. jz parm_block_considered
  377. les di,pParmBlk
  378. les di,es:[di].lpcmdline
  379. mov cx,es:[di]
  380. sub cx,127 ; account for terminating 0Dh
  381. jbe parm_block_considered
  382. add si,cx
  383. add si,15
  384. and si,NOT 15
  385. parm_block_considered:
  386. add si,TDBsize+15 ; Room for task data and paragraph aligned.
  387. ; xor ax,ax ; Room for EMM save area if needed.
  388. ; mov al,fEMM
  389. ; add si,ax
  390. and si,0FFF0h
  391. mov di,si
  392. mov cl,4
  393. shr si,cl
  394. ifdef WOW
  395. ; We need to ensure task handles are unique across multiple WOW VDMs
  396. ; on Windows NT, so that for example the undocumented feature of
  397. ; passing a 16-bit htask to Win32 Post(App|Thread)Message instead
  398. ; of a thread ID will work reliably with multiple WOW VDMs.
  399. ;
  400. ; To accomplish this we call WowReserveHtask, which will return
  401. ; the htask if the htask (ptdb) was previously unused and has
  402. ; been reserved for us. If it returns 0 another VDM is already
  403. ; using that value and so we need to allocate another and try again.
  404. ; To avoid risking exhausting low memory, we allocate memory for the
  405. ; TDB once using GlobalDOSAlloc, then clone it using AllocSelector.
  406. ; We test this cloned selector value using WowReserveHtask, if it
  407. ; fails we get another clone until one works. Then we free all but
  408. ; the clone we'll return, and magically swap things around so that
  409. ; the cloned selector owns the TDB memory and then free the original
  410. ; selector from GlobalDOSAlloc
  411. ;
  412. xor dx,dx ; Make size of allocation a dword
  413. regptr xsize,dx,di
  414. cCall GlobalDOSAlloc,<xsize>
  415. or ax,ax
  416. jnz @f
  417. jmp ats6 ; Return zero for failure.
  418. @@: push di ; save TDB size on stack
  419. push ax ; save GlobalDOSAlloc selector on stack
  420. mov di,ax ; and in DI
  421. cCall WowReserveHtask,<ax> ; returns htask or 0
  422. or ax,ax ; Is this selector value avail as htask?
  423. jz MustClone ; no, start cloning loop
  424. pop ax ; htask to return
  425. pop di ; TDB size
  426. jmps NoClone
  427. MustClone:
  428. xor cx,cx ; count of clone selectors
  429. xor si,si ; no selector to return yet
  430. AnotherHtask:
  431. push cx
  432. cCall AllocSelector,<di> ; clone the selector
  433. pop cx
  434. or ax,ax
  435. jz FreeAnyHtasks ; Out of selectors cleanup and exit
  436. push ax ; save cloned selector on stack
  437. inc cx
  438. push cx
  439. cCall WowReserveHtask,<ax> ; returns htask or 0
  440. pop cx
  441. or ax,ax
  442. jz AnotherHtask ; conflict
  443. mov si,ax ; SI = selector to return
  444. pop bx ; pop the selector we're returning
  445. dec cx
  446. jcxz @f
  447. FreeLoop:
  448. pop bx ; pop an allocated selector from stack
  449. push cx
  450. cCall FreeSelector,<bx>
  451. pop cx
  452. dec cx
  453. FreeAnyHtasks:
  454. jcxz @f ; have we popped all the allocated selectors? Yes
  455. jmps FreeLoop ; No
  456. @@: mov ax,si
  457. or si,si
  458. jnz @f
  459. pop ax ; original selector from GlobalDOSAlloc
  460. cCall GlobalDOSFree,<ax>
  461. pop di
  462. jmp ats6
  463. @@:
  464. ; SI is selector to return, top of stack is original GlobalDOSAlloc
  465. ; selector. We need to free the original selector and make the clone
  466. ; selector "own" the memory so it will be freed properly by GlobalDOSFree
  467. ; during task cleanup.
  468. pop di ; DI = original GlobalDOSAlloc selector
  469. push ds
  470. mov ds, pGlobalHeap
  471. UnSetKernelDS
  472. .386
  473. cCall far_get_arena_pointer32,<di>
  474. push eax
  475. cCall FarAssociateSelector32,<di,0,0>
  476. pop eax
  477. mov ds:[eax].pga_handle, si
  478. cCall FarAssociateSelector32,<si,eax>
  479. .286p
  480. pop ds
  481. ReSetKernelDS
  482. cCall FreeSelector,<di>
  483. mov ax,si ; AX is the final TDB selector/handle.
  484. pop di ; TDB size
  485. NoClone:
  486. else
  487. xor dx,dx ; Make size of allocation a dword
  488. regptr xsize,dx,di
  489. cCall GlobalDOSAlloc,<xsize>
  490. or ax,ax
  491. jnz @f
  492. jmp ats6 ; Return zero for failure.
  493. @@:
  494. endif
  495. mov es, ax
  496. xor ax, ax ; zero allocated block
  497. mov cx, di
  498. shr cx, 1
  499. xor di, di
  500. rep stosw
  501. mov ax, es
  502. ats2a:
  503. cCall FarSetOwner,<ax,ax> ; Set TDB owner to be itself
  504. cmp fWOA,0 ; Is this WinOldApp?
  505. mov ds,ax
  506. UnSetKernelDS
  507. jz no_it_isnt
  508. or ds:[TDB_flags],TDBF_WINOLDAP
  509. no_it_isnt:
  510. ; Initialize the task stack.
  511. mov si,1 ; 1 for show means open window
  512. les di,pParmBlk
  513. mov ax,es
  514. or ax,di
  515. jnz @F
  516. jmp ats4 ; AX = DI = 0 if no parmblock
  517. @@: xor ax,ax ; Skip past EMM save area and
  518. push ds
  519. xor dx, dx
  520. push es
  521. mov es,pExe
  522. mov dx,es:[ne_flags]
  523. pop es
  524. test dx,NEPROT
  525. jz @F
  526. or ds:[TDB_flags],TDBF_OS2APP
  527. or ds:[TDB_ErrMode],08000h ; don't prompt for .DLL's
  528. @@:
  529. call MapDStoDATA
  530. ReSetKernelDS
  531. test dx,NEPROT ; OS/2 app?
  532. mov dx,TopPDB ; DX has segment of parent PDB
  533. jz use_kernel_TDB
  534. ; %OUT This should probably be Win_PDB
  535. mov dx,cur_DOS_PDB ; inherit parent's stuff
  536. use_kernel_TDB:
  537. pop ds
  538. UnSetKernelDS
  539. push dx ; yes, get address of PDB
  540. push es
  541. mov si,(TDBsize+15) and not 15 ; Round up TDB size
  542. cCall AllocSelector,<ds> ; Get us an alias selector
  543. or ax, ax ; did we get it?
  544. jnz ats_gotsel
  545. mov bx, ds ; No, tidy up
  546. mov ds, ax ; We will current ds, so zero it
  547. cCall GlobalDOSFree,<bx> ; Free the memory
  548. pop es
  549. pop dx
  550. xor ax, ax
  551. jmp ats6
  552. ats_gotsel:
  553. xor dx, dx
  554. cCall LongPtrAdd,<ax,dx,dx,si>
  555. mov si, dx ; SI = selector of new PDB
  556. pop es
  557. pop dx
  558. regptr esbx,es,bx ; es:bx points at parm block
  559. mov bx,di
  560. mov cx,256 ; just include enough room for PDB
  561. cCall BuildPDB,<dx,si,esbx,cx,fWOA>; go build it
  562. mov ax,si ; link on another PDB
  563. push ds
  564. call MapDStoDATA
  565. ReSetKernelDS
  566. xchg HeadPDB,ax
  567. mov es,si
  568. mov es:[PDB_Chain],ax
  569. les di,pParmBlk
  570. push si
  571. lds si,es:[di].lpfcb1
  572. UnSetKernelDS
  573. mov di,PDB_5C_FCB
  574. pop es
  575. mov cx,ds
  576. or cx,si
  577. jz ats3b
  578. mov cx,ds:[si]
  579. inc cx
  580. inc cx
  581. cmp cx,24h
  582. jbe ats3a
  583. mov cx,24h
  584. ats3a: rep movsb
  585. ats3b: mov si,es
  586. pop ds
  587. mov ax,env_seg
  588. or ax,ax
  589. jz no_new_env
  590. mov es:[PDB_environ],ax
  591. no_new_env:
  592. ats4: mov es,pExe
  593. mov ds:[TDB_pModule],es ; Do this before InitTaskEMS
  594. mov ax,comline_start ;!!! just for now os2
  595. mov ds:[TDB_Validity],ax
  596. push si
  597. push ds
  598. push ds
  599. push es
  600. pop ds
  601. pop es
  602. mov di,TDB_ModName
  603. mov si,ds:[ne_restab]
  604. lodsb ; get no of bytes in name
  605. cbw
  606. cmp ax,8
  607. jbe @F
  608. mov ax, ds
  609. krDebugOut <DEB_WARN or DEB_krLoadMod>, "Module Name %AX0 (%AX1) too long"
  610. mov ax,8
  611. @@: mov cx,ax
  612. cld
  613. rep movsb
  614. ifdef WOW
  615. ; (see other bug #74369 note)
  616. ; Load the App compatibility flags
  617. ; This ifdef WOW chunk is the same place as Win'95 task.asm to help get compat
  618. ; flags loaded sooner
  619. mov cx,ds:[ne_expver]
  620. mov es:[TDB_ExpWinVer],cx
  621. cCall SetAppCompatFlags, <es>
  622. mov es:[TDB_CompatFlags], ax
  623. mov es:[TDB_CompatFlags2], dx
  624. if KDEBUG
  625. mov bx, ax
  626. or bx, dx
  627. jz @F
  628. krDebugOut DEB_WARN, "Backward compatibility hack enabled: #dx#AX"
  629. @@:
  630. endif
  631. endif
  632. ; initialize the interrupt vectors
  633. mov di,TDB_INTVECS
  634. call MapDStoDATA
  635. ReSetKernelDS
  636. ife ROM
  637. mov ds,MyCSAlias
  638. assumes ds,CODE
  639. mov si,codeOffset prevInt00proc
  640. else
  641. mov si,dataOffset prevInt00proc
  642. endif
  643. mov cx,(4 * numTaskInts)/2
  644. rep movsw
  645. assumes ds,nothing
  646. pop ds
  647. pop si
  648. cCall FarCreateTask ;,<fPrev>
  649. jnc @F
  650. jmp ats6
  651. @@:
  652. push ds
  653. call MapDStoDATA
  654. ReSetKernelDS
  655. mov es,curTDB ; inherit the parents
  656. pop ds
  657. UnSetKernelDS
  658. mov ds:[TDB_PDB],si ; save new PDB
  659. or si,si ; do we have a new PDB?
  660. jnz @F ; zero means no
  661. mov si,es:[TDB_PDB]
  662. mov ds:[TDB_PDB],si
  663. @@: mov ds:[TDB_Parent],es
  664. ;
  665. ; Inherit parent's wow compatibiltiy flags
  666. ; Special code is required in wkman.c to exploit this
  667. mov ax,es:[TDB_WOWCompatFlags]
  668. mov ds:[TDB_WOWCompatFlags],ax
  669. mov ax,es:[TDB_WOWCompatFlags2]
  670. mov ds:[TDB_WOWCompatFlags2],ax
  671. mov ax,es:[TDB_WOWCompatFlagsEx]
  672. mov ds:[TDB_WOWCompatFlagsEx],ax
  673. mov ax,es:[TDB_WOWCompatFlagsEx2]
  674. mov ds:[TDB_WOWCompatFlagsEx2],ax
  675. mov ds:[TDB_thread_tdb],ds
  676. mov ds:[TDB_DTA].off,80h ; set initial DTA
  677. mov ds:[TDB_DTA].sel,si
  678. mov ds:[TDB_sig],TDB_SIGNATURE ; Set signature word.
  679. mov ax,SEG default_sig_handler
  680. mov ds:[TDB_ASignalProc].sel,ax
  681. mov ax,codeOffset default_sig_handler
  682. mov ds:[TDB_ASignalProc].off,ax
  683. ; Initialize the MakeProcInstance Thunks.
  684. cCall AllocDStoCSAlias,<ds>
  685. mov ds:[TDB_MPI_Sel],ax
  686. mov ds:[TDB_MPI_Thunks],0
  687. mov ds:[TDB_MPI_Thunks].2,MPIT_SIGNATURE
  688. mov bx,TDB_MPI_Thunks + THUNKSIZE-2
  689. mov cx,THUNKELEM-1
  690. mov dx,bx
  691. mp1: add dx,THUNKSIZE
  692. .errnz THUNKELEM and 0FF00h
  693. mov ds:[bx],dx
  694. mov bx,dx
  695. loop mp1
  696. mov ds:[bx],cx
  697. mov si, ds
  698. mov di, ax
  699. call MapDStoDATA
  700. ReSetKernelDS
  701. mov ds, pGlobalHeap
  702. UnSetKernelDS
  703. if PMODE32
  704. .386
  705. cCall far_get_arena_pointer32,<si>
  706. cCall FarAssociateSelector32,<di, eax>
  707. .286p
  708. else
  709. cCall far_get_arena_pointer,<si>
  710. cCall FarAssociateSelector,<di, ax>
  711. endif
  712. mov ax, si
  713. mov ds, si
  714. ats6:
  715. cEnd
  716. ;-----------------------------------------------------------------------;
  717. ; pass_environment
  718. ;
  719. ;
  720. ; Entry:
  721. ;
  722. ; Returns:
  723. ; AX = seg of new env if any
  724. ; DX = start of comline
  725. ;
  726. ; Error Return:
  727. ; AX = -1
  728. ;
  729. ; Registers Destroyed:
  730. ;
  731. ; History:
  732. ; Wed 27-Dec-1989 23:36:25 -by- David N. Weise [davidw]
  733. ; Wrote it!
  734. ;-----------------------------------------------------------------------;
  735. assumes ds,nothing
  736. assumes es,nothing
  737. ifdef WOW
  738. cProc pass_environment,<PUBLIC,NEAR>,<di,si,ds>
  739. parmW pExe
  740. parmD pParmBlk
  741. cBegin
  742. ReSetKernelDS
  743. test fBooting,1
  744. jz @F
  745. xor ax,ax
  746. jmp pe_exit
  747. @@:
  748. cCall WowPassEnvironment,<cur_DOS_PDB, pParmBlk, pExe>
  749. or ax,ax
  750. jz pe_error_exit
  751. cCall FarSetOwner,<ax,pExe> ; Make this new guy the owner
  752. jmps pe_exit
  753. pe_error_exit:
  754. mov ax, -1
  755. pe_exit:
  756. cEnd
  757. else
  758. cProc pass_environment,<PUBLIC,NEAR>,<di,si,ds>
  759. parmW pExe
  760. parmD pParmBlk
  761. localW myEnv
  762. cBegin
  763. ReSetKernelDS
  764. cld
  765. test fBooting,1
  766. jz @F
  767. xor ax,ax
  768. jmp pe_exit
  769. @@:
  770. cCall WowPassEnvironment,<Win_PDB, cur_DOS_PDB, pParmBlk, pExe>
  771. mov es,curTDB
  772. mov bl,es:[TDB_flags]
  773. @@:
  774. ; massage environment
  775. les di,pParmBlk
  776. mov ax,es:[di].envseg
  777. or ax,ax
  778. jnz pe_given_env
  779. ; %OUT This should probably be Win_PDB
  780. mov ds,cur_DOS_PDB
  781. UnsetKernelDS
  782. mov ax,ds:[PDB_environ]
  783. pe_given_env:
  784. mov myEnv,ax
  785. mov es,ax ; ES => environment
  786. xor ax,ax
  787. mov cx,-1
  788. xor di,di
  789. @@: repnz scasb
  790. cmp es:[di],al
  791. jnz @B
  792. neg cx
  793. ; dec cx ; include space for extra 0
  794. push cx ; length of environment
  795. mov dx,cx
  796. ; MORE TEST CODE TO SEE IF IT FIXES THE PROBLEM.
  797. mov es,pExe
  798. test es:[ne_flags],NEPROT
  799. jnz @f
  800. mov cx,3 ; Save room for magic word and nul
  801. add dx,cx
  802. push 8000h ; No command line after the env.
  803. jmps pe_got_com_len
  804. @@:
  805. les di,pParmBlk
  806. test bl,TDBF_OS2APP ; execer an OS/2 app?
  807. jz pe_execer_dos_app
  808. les di,es:[di].lpCmdLine
  809. mov cx,-1
  810. repnz scasb
  811. repnz scasb ; get both strings
  812. neg cx
  813. add dx,cx
  814. dec cx ; length of command line
  815. or ch,80h ; mark special
  816. push cx
  817. jmps pe_got_com_len
  818. pe_execer_dos_app:
  819. inc es:[di].lpCmdLine.off
  820. les di,es:[di].lpCmdLine
  821. xor cx,cx
  822. mov cl,es:[di][-1] ; length of command line
  823. add dx,cx
  824. inc dx ; We add a '\0' when we move it anyway
  825. push cx
  826. pe_got_com_len:
  827. mov es,pExe
  828. mov di,es:[ne_pfileinfo]
  829. lea di,[di].opfile
  830. mov cx,-1
  831. repnz scasb
  832. neg cx
  833. dec cx
  834. push cx ; length of file name
  835. shl cx,1 ; for program pointer and arg 1
  836. add dx,cx
  837. cCall GlobalAlloc,<ax,ax,dx>
  838. or ax,ax
  839. jz @f
  840. push ax
  841. cCall FarSetOwner,<ax,pExe> ; Make this new guy the owner
  842. pop ax
  843. @@:
  844. mov es,ax
  845. pop dx ; length of filename
  846. pop bx ; length of command line
  847. pop cx ; length of environment
  848. or ax,ax
  849. jz pe_error_exit
  850. mov ds,myEnv
  851. xor di,di
  852. xor si,si
  853. rep movsb
  854. mov ds,pExe
  855. ; MORE TEST CODE TO SEE IF IT FIXED THE PROBLEM
  856. test ds:[ne_flags],NEPROT
  857. jnz @f
  858. mov ax,1
  859. stosw
  860. @@:
  861. mov si,ds:[ne_pfileinfo]
  862. lea si,[si].opfile
  863. mov cx,dx ; length of filename
  864. rep movsb
  865. mov ax,di ; save position of comline start
  866. test bh,80h ; if OS/2 execer comline is correct
  867. jnz @F
  868. mov si,ds:[ne_pfileinfo]
  869. lea si,[si].opfile
  870. mov cx,dx ; length of filename
  871. rep movsb
  872. @@: and bh,NOT 80h
  873. lds si,pParmBlk
  874. lds si,ds:[si].lpCmdLine
  875. mov cx,bx
  876. rep movsb
  877. mov byte ptr es:[di],0 ; zero terminate
  878. mov dx,ax ; comline start
  879. mov ax,es
  880. jmps pe_exit
  881. pe_error_exit:
  882. mov ax,-1
  883. pe_exit:
  884. cEnd
  885. endif
  886. ;-----------------------------------------------------------------------;
  887. ; StartLibrary ;
  888. ; ;
  889. ; Initialize library registers. ;
  890. ; ;
  891. ; Arguments: ;
  892. ; parmW hExe ;
  893. ; parmD lpParms ;
  894. ; parmD startAddr ;
  895. ; ;
  896. ; Returns: ;
  897. ; ;
  898. ; Error Returns: ;
  899. ; AX = 0 ;
  900. ; DS = data segment ;
  901. ; ;
  902. ; Registers Preserved: ;
  903. ; DI,SI ;
  904. ; ;
  905. ; Registers Destroyed: ;
  906. ; BX,CX,DX,ES ;
  907. ; ;
  908. ; Calls: ;
  909. ; GetInstance ;
  910. ; FarMyLock ;
  911. ; ;
  912. ; History: ;
  913. ; ;
  914. ; Thu 04-Jan-1990 22:48:25 -by- David N. Weise [davidw] ;
  915. ; Added support for OS/2 apps. ;
  916. ; ;
  917. ; Sat Apr 18, 1987 08:54:50p -by- David N. Weise [davidw] ;
  918. ; Added this nifty comment block. ;
  919. ;-----------------------------------------------------------------------;
  920. assumes ds,nothing
  921. assumes es,nothing
  922. cProc StartLibrary,<PUBLIC,NEAR>,<ds,si,di>
  923. parmW hExe
  924. parmD lpParms
  925. parmD startAddr
  926. localW hStartSeg
  927. cBegin
  928. cCall MapDStoDATA
  929. ReSetKernelDS
  930. cmp loadTDB,0
  931. je notloading
  932. test kernel_flags,KF_pUID ; All done booting?
  933. jz notloading
  934. mov es,loadTDB
  935. test es:[TDB_Flags],TDBF_OS2APP
  936. jnz notloading
  937. mov ax,hExe
  938. mov es,es:[TDB_LibInitSeg]
  939. mov bx,es:[pStackTop]
  940. xchg es:[bx-2],ax
  941. mov es:[bx],ax
  942. add es:[pStackTop],2
  943. mov ax,hExe
  944. jmp slxx
  945. notloading:
  946. mov si,hExe
  947. mov es,si
  948. test es:[ne_flags],NEPROT
  949. jnz no_user_yet
  950. cmp pSignalProc.sel,0
  951. jz no_user_yet
  952. xor ax,ax
  953. mov bx,40h
  954. cCall pSignalProc,<hExe,bx,ax,ax,ax> ; SignalProc(hModule,40h,wParam,lParam)
  955. no_user_yet:
  956. cCall GetInstance,<si>
  957. mov di,ax
  958. if ROM
  959. cCall FarIsROMObject, <SEG_startAddr>
  960. or ax, ax
  961. jz not_rom_code_segment
  962. mov hStartSeg, 0
  963. jmp sl_got_handle
  964. not_rom_code_segment:
  965. endif
  966. cCall IGlobalHandle,<SEG_startAddr>
  967. xchg startAddr.sel,dx
  968. mov hStartSeg,ax
  969. if ROM
  970. sl_got_handle:
  971. endif
  972. ;** Send the SDM_LOADDLL notification
  973. mov bx,startAddr.off
  974. mov cx,startAddr.sel
  975. mov ax,SDM_LOADDLL
  976. cCall MyFarDebugCall
  977. cmp SEG_startAddr, 0
  978. jnz HaveStart
  979. mov ax, di
  980. jmps slxx
  981. HaveStart:
  982. cCall IGlobalHandle,<di>
  983. mov ds,si
  984. UnSetKernelDS
  985. mov cx,ds:[ne_heap]
  986. mov ds,dx
  987. les si,lpParms
  988. mov ax,es
  989. or ax,ax
  990. jz dont_fault
  991. les si,es:[si].lpcmdline
  992. dont_fault:
  993. mov ax,1 ; An Arts & Letters lib init doesn't
  994. push di ; touch AX!!
  995. ifdef WOW
  996. push cs
  997. push offset RetAddr
  998. pushf
  999. push startAddr.sel
  1000. push startAddr.off
  1001. push ax
  1002. push ds
  1003. push ax
  1004. mov ax,hExe
  1005. mov ds,ax
  1006. pop ax
  1007. push 0 ; hTask (meaningless for a DLL)
  1008. push ds ; hModule
  1009. push ds ; Pointer to module name
  1010. push ds:ne_restab
  1011. push ds ; Pointer to module path
  1012. push word ptr ds:ne_crc+2
  1013. cCall MapDStoDATA
  1014. ReSetKernelDS ds
  1015. push DBG_DLLSTART
  1016. test DebugWOW,DW_DEBUG
  1017. jz skip_bop
  1018. FBOP BOP_DEBUGGER,,FastBop
  1019. .286p
  1020. skip_bop:
  1021. add sp,+14
  1022. pop ds
  1023. UnSetKernelDS ds
  1024. pop ax
  1025. iret
  1026. RetAddr equ $
  1027. else
  1028. cCall SafeCall,<startAddr>
  1029. endif
  1030. pop di ; USER.EXE didn't save DI, maybe others
  1031. or ax,ax
  1032. jz slx
  1033. mov ax,di
  1034. slx:
  1035. push ax
  1036. if ROM
  1037. cmp hStartSeg, 0
  1038. jz @F
  1039. cCall GlobalLRUOldest,<hStartSeg>
  1040. @@:
  1041. endif
  1042. pop ax
  1043. slxx:
  1044. cEnd
  1045. ;-----------------------------------------------------------------------;
  1046. ; StartTask ;
  1047. ; ;
  1048. ; Sets up the standard register values for a Windows task. ;
  1049. ; ;
  1050. ; Arguments: ;
  1051. ; HANDLE hPrev = a previous instance ;
  1052. ; HANDLE hExe = the EXE header ;
  1053. ; FARP stackAddr = the normal task stack address (initial SS:SP) ;
  1054. ; FARP startAddr = the normal task start address (initial CS:IP) ;
  1055. ; ;
  1056. ; Returns: ;
  1057. ; AX = HANDLE ;
  1058. ; ;
  1059. ; Error Returns: ;
  1060. ; AX = NULL ;
  1061. ; ;
  1062. ; Registers Preserved: ;
  1063. ; ;
  1064. ; Registers Destroyed: ;
  1065. ; ;
  1066. ; Calls: ;
  1067. ; GetInstance ;
  1068. ; FarMyLock ;
  1069. ; ;
  1070. ; History: ;
  1071. ; ;
  1072. ; Tue Apr 21, 1987 06:41:05p -by- David N. Weise [davidw] ;
  1073. ; Added the EMS initialization of the entry tables in page 0. ;
  1074. ; ;
  1075. ; Thu Dec 11, 1986 11:38:53a -by- David N. Weise [dnw] ;
  1076. ; Removed the superfluous call to calculate the largesr NR seg. ;
  1077. ; ;
  1078. ; Fri Sep 19, 1986 12:08:23p -by- Charles Whitmer [cxw] ;
  1079. ; Made it return 0000 on error rather than terminate. ;
  1080. ; ;
  1081. ; Thu Sep 18, 1986 02:33:39p -by- Charles Whitmer [cxw] ;
  1082. ; Wrote it. ;
  1083. ;-----------------------------------------------------------------------;
  1084. assumes ds,nothing
  1085. assumes es,nothing
  1086. cProc StartTask,<PUBLIC,NEAR>,<si,di>
  1087. parmW hPrev
  1088. parmW hExe
  1089. parmD stackAddr
  1090. parmD startAddr
  1091. cBegin
  1092. cCall MapDStoDATA
  1093. ReSetKernelDS
  1094. xor di,di
  1095. cmp loadTDB,di
  1096. jnz st1
  1097. jmp stx
  1098. stfail0:
  1099. xor ax,ax
  1100. pop ds
  1101. jmp stfail
  1102. st1: push ds
  1103. cmp stackAddr.sel,di
  1104. jz stfail0
  1105. cmp startAddr.sel,di
  1106. jz stfail0
  1107. mov ds,loadTDB
  1108. UnSetKernelDS
  1109. cmp ds:[TDB_sig],TDB_SIGNATURE
  1110. jnz stfail0
  1111. ; Get new task stack
  1112. cCall IGlobalHandle,<SEG_stackAddr>
  1113. mov ds:[TDB_taskSS],dx
  1114. mov ax,stackAddr.off
  1115. sub ax,(SIZE TASK_REGS)
  1116. mov ds:[TDB_taskSP],ax
  1117. ; get my instance
  1118. cCall GetInstance,<hExe>
  1119. mov di,ax
  1120. mov ds:[TDB_Module],ax
  1121. ; find my real code segment
  1122. cCall IGlobalHandle,<SEG_startAddr>
  1123. or dx,dx
  1124. jz stfail0
  1125. mov startAddr.sel,dx
  1126. ; find my real data segment
  1127. cCall IGlobalHandle,<di> ; DI = handle of DGROUP
  1128. mov si,dx ; SI = address of DGROUP
  1129. if KDEBUG
  1130. ; Set up the allocBreak globals if needed
  1131. cCall SetupAllocBreak,<ds>
  1132. endif ;KDEBUG
  1133. ; copy junk from hExe -> TDB
  1134. mov es,hExe
  1135. mov cx,es:[ne_expver]
  1136. mov ds:[TDB_ExpWinVer],cx
  1137. mov cx,es:[ne_stack] ; CX = STACKSIZE
  1138. mov dx,es:[ne_heap] ; DX = HEAPSIZE
  1139. ; set up the task registers
  1140. test es:[ne_flags],NEPROT
  1141. jnz st_OS2_binary
  1142. les bx,dword ptr ds:[TDB_TaskSP]
  1143. mov es:[bx].TASK_AX,0 ; Task AX = NULL
  1144. mov ax,ds:[TDB_PDB]
  1145. mov es:[bx].TASK_ES,ax ; Task ES = PDB
  1146. mov es:[bx].TASK_DI,di ; Task DI = hInstance or hExe
  1147. mov es:[bx].TASK_DS,si ; Task DS = data segment
  1148. mov ax,hPrev
  1149. mov es:[bx].TASK_SI,ax ; Task SI = previous instance
  1150. mov es:[bx].TASK_BX,cx ; Task BX = STACKSIZE
  1151. mov es:[bx].TASK_CX,dx ; Task CX = HEAPSIZE
  1152. mov es:[bx].TASK_BP,1 ; Task BP = 1 (far frame)
  1153. jmps st_regs_set
  1154. st_OS2_binary:
  1155. push di
  1156. mov es,ds:[TDB_PDB]
  1157. mov di,es:[PDB_environ]
  1158. les bx,dword ptr ds:[TDB_TaskSP]
  1159. mov es:[bx].TASK_AX,di ; Task AX = environment
  1160. mov es:[bx].TASK_DX,cx ; Task DX = STACKSIZE
  1161. lsl cx,si
  1162. inc cx
  1163. mov es:[bx].TASK_CX,cx ; Task CX = Length of data segment
  1164. mov ax,ds:[TDB_pModule]
  1165. mov es:[bx].TASK_DI,ax ; Task DI = hExe
  1166. mov es:[bx].TASK_SI,dx ; Task SI = HEAPSIZE
  1167. mov es:[bx].TASK_DS,si ; Task DS = data segment
  1168. mov es:[bx].TASK_ES,0 ; Task ES = 0
  1169. mov es:[bx].TASK_BP,1 ; Task BP = 1 (far frame)
  1170. xor ax,ax
  1171. xchg ax,ds:[TDB_Validity]
  1172. mov es:[bx].TASK_BX,ax ; Task BX = offset in env of comline
  1173. pop di
  1174. st_regs_set:
  1175. pop ds
  1176. push ds
  1177. ReSetKernelDS
  1178. test Kernel_Flags[2],KF2_PTRACE ;TOOLHELP.DLL and/or WINDEBUG.DLL?
  1179. jz st_NoPTrace
  1180. mov ax,startAddr.sel
  1181. mov ptrace_app_entry.sel,ax
  1182. mov ax,startAddr.off
  1183. mov ptrace_app_entry.off,ax
  1184. mov ax,SEG CVW_HACK
  1185. mov ds,ax
  1186. UnSetKernelDS
  1187. mov ax,codeOffset CVW_Hack
  1188. jmps st_PTraceHere
  1189. st_NoPTrace:
  1190. lds ax,startAddr ; Task CS:IP = start address
  1191. UnSetKernelDS
  1192. st_PTraceHere:
  1193. mov es:[bx].TASK_CS,ds
  1194. mov es:[bx].TASK_IP,ax
  1195. pop ds
  1196. ReSetKernelDS
  1197. stx: mov ax,di
  1198. stfail:
  1199. cEnd
  1200. ;-----------------------------------------------------------------------;
  1201. ; InitTask ;
  1202. ; ;
  1203. ; This should be the first thing called by app when first started. ;
  1204. ; It massages the registers, massages the command line and inits ;
  1205. ; the heap. ;
  1206. ; ;
  1207. ; Arguments: ;
  1208. ; ;
  1209. ; When a windows application starts up the registers look ;
  1210. ; like this: ;
  1211. ; ;
  1212. ; AX = 0 ;
  1213. ; BX = stack size ;
  1214. ; CX = heap size ;
  1215. ; DX = ? ;
  1216. ; DI = hInstance ;
  1217. ; SI = hPrevInstance ;
  1218. ; BP = 0 ;
  1219. ; ES = Segment of Program Segment Prefix (see page E-8) ;
  1220. ; DS = Applications DS ;
  1221. ; SS = DS ;
  1222. ; SP = stack area ;
  1223. ; ;
  1224. ; FCB1 field at PSP:5CH contains up to 24h bytes of binary data. ;
  1225. ; Windows apps get their ShowWindow parameter in the first word of ;
  1226. ; of this data. ;
  1227. ; ;
  1228. ; Returns: ;
  1229. ; AX = PSP address ;
  1230. ; CX = stack limit ;
  1231. ; DX = command show ;
  1232. ; ES:BX = command line ;
  1233. ; ;
  1234. ; Error Returns: ;
  1235. ; ;
  1236. ; Registers Preserved: ;
  1237. ; ;
  1238. ; Registers Destroyed: ;
  1239. ; ;
  1240. ; Calls: ;
  1241. ; LocalInit ;
  1242. ; FarEMS_FirstTime ;
  1243. ; ;
  1244. ; History: ;
  1245. ; ;
  1246. ; Mon 11-Sep-1989 19:13:52 -by- David N. Weise [davidw] ;
  1247. ; Remove entry of AX = validity check. ;
  1248. ; ;
  1249. ; Wed Mar 16, 1988 22:45:00a -by- T.H. [ ] ;
  1250. ; Fix bug in exit path. It was not popping the saved DS from the ;
  1251. ; far call frame properly. Normally, this is not a problem (since ;
  1252. ; it does indeed save the DS register across the entire routine), ;
  1253. ; but if the RET has to go through a RetThunk, the saved DS is not ;
  1254. ; really the original DS value, but a special value needed by the ;
  1255. ; INT3F RetThunk code. This causes a crash when something in this ;
  1256. ; routine (like the call to UserInitDone) causes our calling code ;
  1257. ; segment to be discarded. ;
  1258. ; ;
  1259. ; Sat Apr 18, 1987 08:43:54p -by- David N. Weise [davidw] ;
  1260. ; Added this nifty comment block. ;
  1261. ;-----------------------------------------------------------------------;
  1262. STACKSLOP equ 150 ; stack slop for interrupt overhead
  1263. assumes ds,nothing
  1264. assumes es,nothing
  1265. ; ES = TDB
  1266. public do_libinit
  1267. do_libinit proc near
  1268. push si
  1269. push es
  1270. mov si,es:[TDB_LibInitOff]
  1271. mov es,cx
  1272. libinit_loop:
  1273. cld
  1274. lods word ptr es:[si]
  1275. or ax,ax
  1276. jz libinit_done
  1277. push es
  1278. mov es,ax
  1279. cmp es:[ne_magic],NEMAGIC
  1280. jne libinit_loop1
  1281. mov ax,-1
  1282. push es
  1283. cCall StartProcAddress,<es,ax>
  1284. pop es
  1285. ;;; jcxz libinit_loop1
  1286. xor cx,cx
  1287. cCall StartLibrary,<es,cx,cx,dx,ax>
  1288. or ax,ax
  1289. jnz libinit_loop1
  1290. mov ax,4CF0h
  1291. DOSFCALL
  1292. libinit_loop1:
  1293. pop es
  1294. jmp libinit_loop
  1295. libinit_done:
  1296. mov si,es
  1297. cCall GlobalUnlock,<si>
  1298. cCall GlobalFree,<si>
  1299. pop es
  1300. mov es:[TDB_LibInitSeg],0
  1301. mov es:[TDB_LibInitOff],0
  1302. pop si
  1303. ret
  1304. do_libinit endp
  1305. assumes ds,nothing
  1306. assumes es,nothing
  1307. cProc InitTask,<PUBLIC,FAR>
  1308. cBegin nogen
  1309. pop ax ; Get return address
  1310. pop dx
  1311. mov ss:[pStackMin],sp ; Save bottom of stack
  1312. mov ss:[pStackBot],sp
  1313. sub bx,sp ; Compute top of stack
  1314. neg bx
  1315. add bx,STACKSLOP
  1316. mov ss:[pStackTop],bx ; Setup for chkstk
  1317. xor bp,bp ; Initial stack frame
  1318. push bp ; is not a far frame as there
  1319. mov bp,sp ; is no return address
  1320. push dx ; Push return address back on
  1321. push ax
  1322. inc bp
  1323. push bp
  1324. mov bp,sp
  1325. push ds
  1326. jcxz noheap ; Initialize local heap if any
  1327. xor ax,ax
  1328. push es
  1329. cCall LocalInit,<ax,ax,cx>
  1330. pop es
  1331. or ax,ax
  1332. jnz noheap
  1333. push ds
  1334. jmp noinit
  1335. noheap:
  1336. push es
  1337. cCall GetCurrentTask
  1338. mov es,ax
  1339. mov cx,es:[TDB_LibInitSeg]
  1340. jcxz no_libinit
  1341. call do_libinit
  1342. no_libinit:
  1343. ifdef WOW
  1344. ; (see other bug #74369 note)
  1345. ; App compatibility flags are set during CreateTask time to make them avilable
  1346. ; to .dll's that are loaded by do_libinit (this is the same as Win'95)
  1347. else
  1348. call SetAppCompatFlags
  1349. mov es:[TDB_CompatFlags], ax
  1350. mov es:[TDB_CompatFlags2], dx
  1351. if KDEBUG
  1352. mov bx, ax
  1353. or bx, dx
  1354. jz @F
  1355. krDebugOut DEB_WARN, "Backward compatibility hack enabled: #dx#AX"
  1356. @@:
  1357. endif
  1358. endif
  1359. pop es
  1360. push ds
  1361. cCall MapDStoDATA
  1362. ReSetKernelDS
  1363. test kernel_flags,KF_pUID ; All done booting?
  1364. jnz noboot ; Yes, continue
  1365. or kernel_flags,KF_pUID
  1366. mov fBooting,0
  1367. mov cx,ds
  1368. pop ds ; DS = caller's data segment
  1369. UnSetKernelDS
  1370. push es ; Save ES
  1371. push ax
  1372. push cx
  1373. cCall IGlobalHandle,<ds>
  1374. push ax
  1375. cCall UnlockSegment,<ds>
  1376. xor dx,dx
  1377. cCall GlobalCompact,<dx,dx> ; Compact memory
  1378. xor dx,dx
  1379. cCall GlobalCompact,<dx,dx> ; Once more for completeness
  1380. cCall IGlobalHandle ; ,<ax> from above
  1381. mov ds,dx
  1382. cCall LockSegment,<ds>
  1383. pop cx
  1384. push ds
  1385. mov ds,cx
  1386. ReSetKernelDS
  1387. cmp pUserInitDone.sel,0 ; for Iris's server
  1388. jz no_User_to_call
  1389. call pUserInitDone ; Let USER lock down stuff.
  1390. no_USER_to_call:
  1391. pop ds
  1392. UnSetKernelDS
  1393. pop ax
  1394. pop es
  1395. push ds
  1396. IF PMODE32
  1397. ;** Initialize the reboot stuff here
  1398. push es ; Save across call
  1399. cCall KRebootInit ; Local reboot init code
  1400. pop es
  1401. ENDIF
  1402. noboot:
  1403. mov bx,PDB_DEF_DTA ; point at command line
  1404. mov cx,bx ; save copy in cx
  1405. cmp bh,es:[bx] ; any chars in command line?
  1406. je ws3a ; no - exit
  1407. ws1: inc bx ; point to next char
  1408. mov al,es:[bx] ; get the char
  1409. cmp al,' ' ; SPACE?
  1410. je ws1
  1411. cmp al,9 ; TAB?
  1412. je ws1
  1413. mov cx,bx ; save pointer to beginning
  1414. dec bx ; compensate for next inc
  1415. ws2: inc bl ; move to next char
  1416. jz ws3a ; bailout if wrapped past 0FFh
  1417. cmp byte ptr es:[bx],13 ; end of line?
  1418. jne ws2
  1419. ws3:
  1420. mov byte ptr es:[bx],0 ; null terminate the line
  1421. ws3a:
  1422. mov bx,cx ; ES:BX = command line
  1423. mov cx,ss:[pStackTop] ; CX = stack limit
  1424. mov dx,1 ; DX = default cmdshow
  1425. cmp word ptr es:[PDB_5C_FCB],2 ; Valid byte count?
  1426. jne wsa4 ; No, use default
  1427. mov dx,word ptr es:[PDB_5C_FCB][2] ; Yes, DX = passed cmdshow
  1428. wsa4:
  1429. mov ax,es ; AX = PSP address
  1430. noinit:
  1431. pop ds
  1432. ; THIS is correct way to pop the call frame. Must pop the saved
  1433. ; DS properly from stack (might have been plugged with a RetThunk).
  1434. sub bp,2
  1435. mov sp,bp
  1436. pop ds
  1437. pop bp
  1438. dec bp
  1439. ret
  1440. cEnd nogen
  1441. ;-----------------------------------------------------------------------;
  1442. ; InitLib ;
  1443. ; ;
  1444. ; Does what it says. ;
  1445. ; ;
  1446. ; Arguments: ;
  1447. ; CX = # bytes wanted for heap ;
  1448. ; ;
  1449. ; Returns: ;
  1450. ; ES:SI => null command line ;
  1451. ; ;
  1452. ; Error Returns: ;
  1453. ; CX = 0 ;
  1454. ; ;
  1455. ; Registers Preserved: ;
  1456. ; DI,DS ;
  1457. ; ;
  1458. ; Registers Destroyed: ;
  1459. ; AX,BX,DX ;
  1460. ; ;
  1461. ; Calls: ;
  1462. ; LocalInit ;
  1463. ; ;
  1464. ; History: ;
  1465. ; ;
  1466. ; Sat Apr 18, 1987 08:31:27p -by- David N. Weise [davidw] ;
  1467. ; Added this nifty comment block. ;
  1468. ;-----------------------------------------------------------------------;
  1469. assumes ds,nothing
  1470. assumes es,nothing
  1471. cProc InitLib,<PUBLIC,FAR>
  1472. cBegin nogen
  1473. xor ax,ax
  1474. jcxz noheap1 ; Done if no heap
  1475. mov si,cx
  1476. cCall LocalInit,<ax,ax,cx>
  1477. jcxz noheap1 ; Done if no heap
  1478. mov cx,si
  1479. noheap1:
  1480. push ds
  1481. cCall MapDStoDATA
  1482. push ds
  1483. pop es
  1484. pop ds
  1485. mov si,codeOFFSET nullcomline
  1486. ret
  1487. cEnd nogen
  1488. if KDEBUG
  1489. if 0
  1490. ;-----------------------------------------------------------------------
  1491. ; SetupAllocBreak
  1492. ;
  1493. ; Initializes the allocation break globals
  1494. ; from the ALLOCBRK environment variable.
  1495. ;
  1496. ; ALLOCBRK=MODULE,0x12345678
  1497. ;
  1498. ; Assumes:
  1499. ; DS = loadTDB
  1500. ;
  1501. ; Trashes:
  1502. ; ES, SI, AX, BX, CX, DX
  1503. ;
  1504. szALLOCBRK db "ALLOCBRK="
  1505. cchALLOCBRK equ $-szALLOCBRK
  1506. cProc SetupAllocBreak,<NEAR, PUBLIC>,<SI>
  1507. cBegin
  1508. mov es,ds:[TDB_PDB]
  1509. mov es,es:[PDB_environ]
  1510. lea bx,szALLOCBRK
  1511. mov dx,cchALLOCBRK
  1512. call LookupEnvString
  1513. or bx,bx
  1514. jz nomatch
  1515. ;
  1516. ; See if TDB_ModName is the same as the ALLOCBRK= module.
  1517. ;
  1518. mov si,TDB_ModName
  1519. modloop:
  1520. mov al,es:[bx] ; get next environment char
  1521. or al,al
  1522. jz nomatch ; if at end of environment, no match
  1523. cmp al,','
  1524. jz match ; if at comma, then they might match
  1525. cmp al,ds:[si]
  1526. jnz nomatch
  1527. inc bx ; advance ptrs and try next char
  1528. inc si
  1529. jmp modloop
  1530. match:
  1531. cmp byte ptr ds:[si],0 ; at end of module name string?
  1532. jnz nomatch
  1533. inc bx ; skip past comma.
  1534. call ParseHex ; parse hex constant into dx:ax
  1535. SetKernelDSNRes es
  1536. mov word ptr es:allocBreak,ax
  1537. mov word ptr es:allocBreak+2,dx
  1538. or ax,dx ; if allocBreak is 0, clear allocTask
  1539. jz @F
  1540. mov ax,ds ; otherwise allocTask = loadTDB.
  1541. @@:
  1542. mov es:allocTask,ax
  1543. xor ax,ax ; reset allocCount
  1544. mov word ptr es:allocCount,ax
  1545. mov word ptr es:allocCount+2,ax
  1546. nomatch:
  1547. cEnd
  1548. ;-----------------------------------------------------------------------
  1549. ; LookupEnvString
  1550. ;
  1551. ; ES -> environment segment
  1552. ; CS:BX -> string to search for (which must include trailing '=')
  1553. ; DX -> length of string to search for
  1554. ;
  1555. ; returns:
  1556. ; es:bx = pointer to environment string past '='
  1557. ;
  1558. cProc LookupEnvString,<NEAR, PUBLIC>,<SI,DI,DS>
  1559. cBegin
  1560. push cs ; ds = cs
  1561. pop ds
  1562. cld
  1563. xor di,di ;start at beginning of environment seg
  1564. lenv_nextstring:
  1565. mov si,bx ;si = start of compare string
  1566. mov cx,dx ;cx = string length
  1567. mov ax,di ;Save current position in env seg
  1568. repe cmpsb
  1569. je lenv_foundit
  1570. mov di,ax ; start at beginning again
  1571. xor ax,ax ; and skip to end.
  1572. xor cx,cx
  1573. dec cx ; cx = -1
  1574. repne scasb
  1575. cmp es:[di],al ;End of environment?
  1576. jne lenv_nextstring ;No, try next string
  1577. xor bx,bx ; BX == NULL == not found.
  1578. jmp short lenv_exit
  1579. lenv_foundit:
  1580. mov bx,di
  1581. lenv_exit:
  1582. cEnd
  1583. ;---------------------------------------------------------------------------
  1584. ;
  1585. ; ParseHex
  1586. ;
  1587. ; Assumes:
  1588. ; es:bx - pointer to hex string of form 0x12345678
  1589. ;
  1590. ; Returns:
  1591. ; Hex value in dx:ax, es:bx pointing to char past constant.
  1592. ;
  1593. ; Trashes:
  1594. ; cx
  1595. ;
  1596. cProc ParseHex,<NEAR, PUBLIC>
  1597. cBegin
  1598. xor dx,dx ; zero break count
  1599. xor ax,ax
  1600. xor cx,cx ; clear hi byte of char
  1601. hexloop:
  1602. mov cl,es:[bx] ; get first digit
  1603. jcxz parse_exit
  1604. inc bx
  1605. cmp cl,' ' ; skip spaces
  1606. jz hexloop
  1607. cmp cl,'x' ; skip 'x' or 'X'
  1608. jz hexloop
  1609. cmp cl,'X'
  1610. jz hexloop
  1611. cmp cl,'0' ; '0'..'9'?
  1612. jb parse_exit
  1613. cmp cl,'9'
  1614. jbe hexdigit
  1615. or cl,'a'-'A' ; convert to lower case
  1616. cmp cl,'a' ; 'a'..'f'?
  1617. jb parse_exit
  1618. cmp cl,'f'
  1619. ja parse_exit
  1620. sub cl,'a'-'0'-10
  1621. hexdigit:
  1622. sub cl,'0'
  1623. add ax,ax ; dx:ax *= 16
  1624. adc dx,dx
  1625. add ax,ax
  1626. adc dx,dx
  1627. add ax,ax
  1628. adc dx,dx
  1629. add ax,ax
  1630. adc dx,dx
  1631. add ax,cx ; add in the new digit
  1632. adc dx,0
  1633. jmp hexloop
  1634. parse_exit:
  1635. cEnd
  1636. endif; 0
  1637. endif ;KDEBUG
  1638. sEnd NRESCODE
  1639. if KDEBUG
  1640. sBegin CODE
  1641. assumes cs,CODE
  1642. ;------------------------------------------------------------------------
  1643. ;
  1644. ; char FAR* GetTaskModNamePtr(HTASK htask)
  1645. ;
  1646. ; Returns a far pointer to a task's module name
  1647. ; Used by SetupAllocBreak to access the task module name.
  1648. ;
  1649. ; Coded in assembly because no C header file that describes
  1650. ; the TDB exists (and it's a little late to create one now)
  1651. ;
  1652. cProc GetTaskModNamePtr,<NEAR, PUBLIC>
  1653. ParmW htask
  1654. cBegin
  1655. mov dx,htask
  1656. mov ax,TDB_ModName
  1657. cEnd
  1658. sEnd CODE
  1659. endif; KDEBUG
  1660. sBegin MISCCODE
  1661. assumes cs, misccode
  1662. assumes ds, nothing
  1663. assumes es, nothing
  1664. externNP MISCMapDStoDATA
  1665. ;-----------------------------------------------------------------------;
  1666. ; GetDOSEnvironment
  1667. ;
  1668. ; Gets a pointer to the current task's starting environment string.
  1669. ; Basically used by DLL's to find the environment.
  1670. ;
  1671. ; Entry:
  1672. ; none
  1673. ;
  1674. ; Returns:
  1675. ; DX:AX = pointer to current task's starting environment string
  1676. ;
  1677. ; Registers Destroyed:
  1678. ;
  1679. ; History:
  1680. ; Tue 13-Jun-1989 20:52:58 -by- David N. Weise [davidw]
  1681. ; Wrote it!
  1682. ;-----------------------------------------------------------------------;
  1683. assumes ds,nothing
  1684. assumes es,nothing
  1685. cProc GetDOSEnvironment,<PUBLIC,FAR>
  1686. cBegin nogen
  1687. push ds
  1688. call GetCurrentTask
  1689. mov ds,ax
  1690. mov ds,ds:[TDB_PDB]
  1691. mov dx,ds:[PDB_environ]
  1692. xor ax,ax
  1693. pop ds
  1694. ret
  1695. cEnd nogen
  1696. ;-----------------------------------------------------------------------;
  1697. ; GetNumTasks ;
  1698. ; ;
  1699. ; Gets the number of tasks (AKA TDB) in the system. ;
  1700. ; ;
  1701. ; Arguments: ;
  1702. ; none ;
  1703. ; ;
  1704. ; Returns: ;
  1705. ; AX = number of tasks ;
  1706. ; ;
  1707. ; Error Returns: ;
  1708. ; ;
  1709. ; Registers Preserved: ;
  1710. ; all ;
  1711. ; ;
  1712. ; Registers Destroyed: ;
  1713. ; ;
  1714. ; Calls: ;
  1715. ; nothing ;
  1716. ; ;
  1717. ; History: ;
  1718. ; ;
  1719. ; Thu Apr 09, 1987 11:34:30p -by- David N. Weise [davidw] ;
  1720. ; Wrote it. ;
  1721. ;-----------------------------------------------------------------------;
  1722. assumes ds,nothing
  1723. assumes es,nothing
  1724. cProc GetNumTasks,<PUBLIC,FAR>
  1725. cBegin nogen
  1726. xor ax,ax
  1727. push ds
  1728. call MISCMapDStoDATA
  1729. ReSetKernelDS
  1730. mov al,num_tasks
  1731. pop ds
  1732. UnSetKernelDS
  1733. ret
  1734. cEnd nogen
  1735. sEnd MISCCODE
  1736. end