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.

3448 lines
76 KiB

  1. PAGE ,132
  2. TITLE LDBOOT - BootStrap procedure
  3. ?DFSTACK = 1
  4. .xlist
  5. include kernel.inc
  6. include newexe.inc
  7. include tdb.inc
  8. include pdb.inc
  9. include eems.inc
  10. include protect.inc
  11. include gpcont.inc
  12. ifdef WOW
  13. include vint.inc
  14. include doswow.inc
  15. endif
  16. .list
  17. if 0; KDEBUG
  18. ifdef WOW
  19. BootTraceOn = 1
  20. BootTrace macro char
  21. push ax
  22. mov ax,char
  23. int 3
  24. pop ax
  25. endm
  26. else
  27. BootTraceOn = 1
  28. BootTrace macro char
  29. push char
  30. call BootTraceChar
  31. endm
  32. endif
  33. else
  34. BootTrace macro char
  35. endm
  36. BootTraceOn = 0
  37. endif
  38. ; Note that the following public constants require special handling
  39. ; for ROM Windows. If you add, delete, or change this list of constants,
  40. ; you must also check the ROM Image Builder.
  41. public __ahshift
  42. public __ahincr
  43. public __0000h
  44. public __0040h
  45. public __A000h
  46. public __B000h
  47. public __B800h
  48. public __C000h
  49. public __D000h
  50. public __E000h
  51. public __F000h
  52. public __ROMBIOS
  53. public __WinFlags
  54. public __flatcs
  55. public __flatds
  56. public __MOD_KERNEL
  57. public __MOD_DKERNEL
  58. public __MOD_USER
  59. public __MOD_DUSER
  60. public __MOD_GDI
  61. public __MOD_DGDI
  62. public __MOD_KEYBOARD
  63. public __MOD_SOUND
  64. public __MOD_SHELL
  65. public __MOD_WINSOCK
  66. public __MOD_TOOLHELP
  67. public __MOD_MMEDIA
  68. public __MOD_COMMDLG
  69. ifdef FE_SB
  70. public __MOD_WINNLS
  71. public __MOD_WIFEMAN
  72. endif ; FE_SB
  73. __ahshift = 3
  74. __ahincr = 1 shl __ahshift
  75. __0000h = 00000h
  76. __0040h = 00040h
  77. __A000h = 0A000h
  78. __B000h = 0B000h
  79. __B800h = 0B800h
  80. __C000h = 0C000h
  81. __D000h = 0D000h
  82. __E000h = 0E000h
  83. __F000h = 0F000h
  84. __ROMBIOS = 0F000h
  85. __WinFlags = 1
  86. __flatcs = 1Bh
  87. __flatds = 23h
  88. __MOD_KERNEL = 0h
  89. __MOD_DKERNEL = 0h
  90. __MOD_USER = 0h
  91. __MOD_DUSER = 0h
  92. __MOD_GDI = 0h
  93. __MOD_DGDI = 0h
  94. __MOD_KEYBOARD = 0h
  95. __MOD_SOUND = 0h
  96. __MOD_SHELL = 0h
  97. __MOD_WINSOCK = 0h
  98. __MOD_TOOLHELP = 0h
  99. __MOD_MMEDIA = 0h
  100. __MOD_COMMDLG = 0h
  101. ifdef FE_SB
  102. __MOD_WINNLS = 0h ; for IME
  103. __MOD_WIFEMAN = 0h ; for WIFEMAN
  104. endif ; FE_SB
  105. BOOTSTACKSIZE = 512
  106. EXTRASTACKSIZE = (4096-BOOTSTACKSIZE)
  107. MultWIN386 EQU 16h ; Reserved to Win386
  108. MW3_ReqInstall EQU 00h ; Installation check
  109. MW3_ReqInstall_Ret_1 EQU 0FFh ; Return number 1
  110. MW3_ReqInstall_Ret_2 EQU 01h ; Return number 2
  111. MW3_ReqInstall_Ret_3 EQU 02h ; Return number 3
  112. MW3_ReqInstall_Ret_4 EQU 03h ; Return number 4
  113. externFP lstrlen
  114. externFP lstrcat
  115. externFP lstrcpy
  116. externFP IGlobalAlloc
  117. externFP IGlobalFree
  118. externFP IGlobalRealloc
  119. externFP LoadModule
  120. externFP IOpenFile
  121. externFP lrusweep
  122. externFP GetExePtr
  123. externFP GetProfileInt
  124. externFP GetPrivateProfileString
  125. externFP GetPrivateProfileInt
  126. externFP GetProcAddress
  127. externFP GetTempDrive
  128. externFP ExitKernel
  129. externFP InternalEnableDOS
  130. externFP FlushCachedFileHandle
  131. externFP SetHandleCount
  132. externFP IPrestoChangoSelector
  133. externFP GPFault
  134. externFP StackFault
  135. externFP invalid_op_code_exception
  136. externFP page_fault
  137. ifdef WOW
  138. externFP divide_overflow
  139. externFP single_step
  140. externFP breakpoint
  141. endif
  142. externFP DiagInit
  143. ifdef WOW
  144. externFP StartWOWTask
  145. externFP AllocSelector_0x47
  146. externW MOD_KERNEL
  147. externW ModCount
  148. externFP WOWGetTableOffsets
  149. externFP WOWDosWowInit
  150. externFP GetShortPathName
  151. endif
  152. if KDEBUG
  153. externFP ValidateCodeSegments
  154. endif
  155. ifdef FE_SB
  156. externFP GetSystemDefaultLangID
  157. endif
  158. externFP TermsrvGetWindowsDir
  159. externW pStackBot
  160. externW pStackMin
  161. externW pStackTop
  162. sBegin CODE
  163. externFP Int21Handler
  164. externFP Int10Handler
  165. externD prevInt10proc
  166. sEnd CODE
  167. ;------------------------------------------------------------------------
  168. ; Data Segment Variables
  169. ;------------------------------------------------------------------------
  170. DataBegin
  171. if SHERLOCK
  172. externW gpEnable
  173. endif
  174. externB graphics
  175. externB fBooting
  176. externB Kernel_flags
  177. externB fChkSum
  178. externB fCheckFree
  179. externB WOAName
  180. externB grab_name
  181. ifndef WOW
  182. externB szUserPro
  183. endif
  184. externB szBootLoad
  185. externB szCRLF
  186. externB szMissingMod
  187. externB szPleaseDoIt
  188. externB fPadCode
  189. ;externW EMScurPID
  190. ;externW PID_for_fake
  191. externW cBytesWinDir
  192. externW cBytesSysDir
  193. externW pGlobalHeap
  194. externW hExeHead
  195. externW MaxCodeSwapArea
  196. externW curTDB
  197. externW f8087
  198. externB fastFP
  199. externW topPDB
  200. externW headTDB
  201. externW winVer
  202. ifndef WOW
  203. externB WinIniInfo
  204. externB PrivateProInfo
  205. endif
  206. externW gmove_stack
  207. externW prev_gmove_SS
  208. externW BaseDsc
  209. externW WinFlags
  210. externW hUser
  211. externW hShell
  212. externW MyCSSeg
  213. externW MyDSSeg
  214. externW MyCSAlias
  215. externB fhCache
  216. externW fhCacheEnd
  217. externW fhCacheLen
  218. externB fPokeAtSegments
  219. externB fExitOnLastApp
  220. externW segLoadBlock
  221. externD pKeyProc
  222. externD pKeyProc1
  223. externW wDefRIP
  224. ife ROM
  225. externW cpShrunk
  226. externW cpShrink
  227. externW hLoadBlock
  228. endif
  229. if ROM
  230. externW selROMTOC
  231. externW selROMLDT
  232. externW sel1stAvail
  233. endif
  234. externD pTimerProc
  235. externD pExitProc
  236. externD pDisableProc
  237. externD lpWindowsDir
  238. externD lpSystemDir
  239. if ROM
  240. externD prevIntx6proc
  241. externD prevInt0Cproc
  242. externD prevInt0Dproc
  243. externD prevInt0Eproc
  244. externD prevInt21proc
  245. externD prevInt3Fproc
  246. endif
  247. ;if KDEBUG and SWAPPRO
  248. ;externD prevIntF0proc
  249. ;endif
  250. externD lpInt21 ; support for NOVELL stealing int 21h
  251. ifdef WOW
  252. externD pFileTable
  253. externW cBytesSys16Dir
  254. externD lpSystem16Dir
  255. externB Sys16Suffix
  256. externW cBytesSys16Suffix
  257. externW cBytesSysWx86Dir
  258. externD lpSystemWx86Dir
  259. externB SysWx86Suffix
  260. externW cBytesSysWx86Suffix
  261. externD pPMDosCURDRV
  262. externD pPMDosCDSCNT
  263. externD pPMDosPDB
  264. externD pPMDosExterr
  265. externD pPMDosExterrLocus
  266. externD pPMDosExterrActionClass
  267. externD pDosWowData
  268. globalW cbRealWindowsDir,0
  269. WINDIR_BUFSIZE equ 121
  270. achWindowsDir DB WINDIR_BUFSIZE DUP(?)
  271. achRealWindowsDir DB WINDIR_BUFSIZE DUP(?)
  272. achSystem16Dir DB 128 DUP(?)
  273. achSystemWx86Dir DB 128 DUP(?)
  274. public cbRealWindowsDir, achRealWindowsDir, achWindowsDir, achSystem16Dir
  275. externB achTermSrvWindowsDir ; windows directory path (for win.ini)
  276. endif
  277. DataEnd
  278. ;------------------------------------------------------------------------
  279. ; INITDATA Variables
  280. ;------------------------------------------------------------------------
  281. DataBegin INIT
  282. ifndef WOW
  283. ; WOW doesn't muck with the WOAName buffer -- we just leave it
  284. ; as WINOLDAP.MOD
  285. externB woa_286
  286. externB woa_386
  287. endif
  288. externB bootExecBlock
  289. externW oNRSeg
  290. externW oMSeg
  291. externW win_show
  292. externD lpBootApp
  293. if ROM
  294. externD lmaROMTOC
  295. staticD MyLmaROMTOC,lmaROMTOC
  296. .errnz opLen
  297. .errnz 8 - opFile
  298. ROMKRNL db 19 ; mocked up open file structure
  299. db 7 dup (0) ; for ROM Kernel
  300. db 'ROMKRNL.EXE',0
  301. endif
  302. staticW initTDBbias,0
  303. staticW initSP,0
  304. staticW initSSbias,0
  305. staticW segNewCS,0
  306. app_name db 68 dup(0)
  307. DataEnd INIT
  308. ;------------------------------------------------------------------------
  309. ; EMSDATA Variables
  310. ;------------------------------------------------------------------------
  311. ;------------------------------------------------------------------------
  312. externNP LoadSegment
  313. externNP genter
  314. externNP gleave
  315. externNP GlobalInit
  316. externNP DeleteTask
  317. externNP BootSchedule
  318. externNP InitFwdRef
  319. externNP SaveState
  320. externNP LKExeHeader
  321. externNP GetPureName
  322. externNP SegmentNotPresentFault
  323. externNP LDT_Init
  324. externNP alloc_data_sel
  325. externNP get_physical_address
  326. externNP set_physical_address
  327. externNP set_sel_limit
  328. externNP free_sel
  329. externFP set_discarded_sel_owner
  330. externNP SelToSeg
  331. externNP DebugDefineSegment
  332. externNP DebugFreeSegment
  333. ife ROM
  334. externNP SwitchToPMODE
  335. externNP LKAllocSegs
  336. endif
  337. if ROM and PMODE32
  338. externFP HocusROMBase
  339. endif
  340. ifdef WOW
  341. externFP WOWFastBopInit
  342. endif
  343. if KDEBUG
  344. ife PMODE32
  345. externNP init_free_to_CCCC
  346. endif
  347. if SWAPPRO
  348. externB fSwapPro
  349. externW hSwapPro
  350. externW cur_dos_pdb
  351. endif
  352. endif
  353. ifdef FE_SB
  354. externFP FarMyIsDBCSTrailByte
  355. endif
  356. ;------------------------------------------------------------------------
  357. sBegin INITCODE
  358. assumes cs,CODE
  359. ife ROM
  360. externD prevIntx6proc
  361. externD prevInt0Cproc
  362. externD prevInt0Dproc
  363. externD prevInt0Eproc
  364. externD prevInt21proc
  365. externD prevInt3Fproc
  366. ifdef WOW
  367. externD prevInt01proc
  368. externD prevInt03proc
  369. externD oldInt00proc
  370. externFP GlobalDosAlloc
  371. externFP GlobalDosFree
  372. endif
  373. endif
  374. externNP TextMode
  375. externNP InitDosVarP
  376. externNP GrowSFTToMax
  377. ifndef WOW
  378. externNP SetUserPro
  379. endif
  380. externNP MyLock
  381. externNP Shrink
  382. externNP DebugDebug
  383. externNP NoOpenFile
  384. externNP NoLoadHeader
  385. if SDEBUG
  386. externNP DebugInit
  387. endif
  388. ;if SWAPPRO
  389. ;externNP INTF0Handler
  390. ;endif
  391. if SDEBUG
  392. szModName db 'KERNEL',0
  393. endif
  394. if ROM
  395. externNP ROMInit
  396. externNP SetOwner
  397. externNP SetROMOwner
  398. externNP alloc_data_sel16
  399. if KDEBUG
  400. externNP CheckGlobalHeap
  401. endif
  402. endif
  403. ifdef WOW
  404. externNP SetOwner
  405. endif
  406. ;-----------------------------------------------------------------------;
  407. ; Bootstrap ;
  408. ; ;
  409. ; Determines whether we should initialize in a smaller amount of ;
  410. ; memory, leaving room for an EEMS swap area. If so, we rep-move the ;
  411. ; code to a lower address, and tell the PSP to report less memory ;
  412. ; available. It then does lots more of stuff. ;
  413. ; ;
  414. ; Arguments: ;
  415. ; DS:0 = new EXE header ;
  416. ; ES:0 = Program Segment Prefix block (PSP) ;
  417. ; SS:SP = new EXE header ;
  418. ; CX = file offset of new EXE header (set by KernStub) ;
  419. ; DS = automatic data segment if there is one ;
  420. ; ;
  421. ; Returns: ;
  422. ; ;
  423. ; Error Returns: ;
  424. ; ;
  425. ; Registers Preserved: ;
  426. ; ;
  427. ; Registers Destroyed: ;
  428. ; ;
  429. ; Calls: ;
  430. ; ;
  431. ; History: ;
  432. ; ;
  433. ; Sat Jun 20, 1987 06:00:00p -by- David N. Weise [davidw] ;
  434. ; Made fast booting work with real EMS. ;
  435. ; ;
  436. ; Tue Apr 21, 1987 06:31:42p -by- David N. Weise [davidw] ;
  437. ; Added some more EMS support. ;
  438. ; ;
  439. ; Thu Apr 09, 1987 02:52:37p -by- David N. Weise [davidw] ;
  440. ; Put back in the movement down if EMS. ;
  441. ; ;
  442. ; Sat Mar 14, 1987 05:55:29p -by- David N. Weise [davidw] ;
  443. ; Added this nifty comment block. ;
  444. ;-----------------------------------------------------------------------;
  445. assumes ds,DATA
  446. assumes es,nothing
  447. assumes ss,nothing
  448. cProc BootStrap,<PUBLIC,NEAR>
  449. cBegin nogen
  450. ifndef NEC_98
  451. if KDEBUG
  452. jmp short Hello_WDEB_End
  453. Hello_WDEB:
  454. db 'Windows Kernel Entry',13,10,0
  455. Hello_WDEB_End:
  456. push ax
  457. push es
  458. push si
  459. xor ax, ax
  460. mov es, ax
  461. mov ax, es:[68h*4]
  462. or ax, es:[68h*4+2]
  463. jz @F
  464. mov ax,cs
  465. mov es,ax
  466. lea si,Hello_WDEB
  467. mov ah,47h
  468. int 68h
  469. @@:
  470. pop si
  471. pop es
  472. pop ax
  473. endif
  474. endif ; NEC_98
  475. BootTrace 'a'
  476. if ROM
  477. call ROMInit ; BX -> LDT, DS -> RAM DGROUP, SI -> start mem
  478. else
  479. cmp ax, "KO" ; OK to boot; set by kernstub.asm
  480. je @F
  481. xor ax, ax
  482. retf
  483. @@:
  484. ; Set up addressibility to our code & data segments
  485. mov MyCSSeg, cs
  486. mov MyDSSeg, ds
  487. endif ;ROM
  488. ifdef WOW
  489. ; Get pointer to sft so that I can find do direct protect mode
  490. ; file IO operations
  491. mov CS:MyCSDS, ds
  492. push es
  493. mov ah,52h ; get pointer to internal vars
  494. int 21h
  495. ;
  496. ; Retrieve some pointers from the DosWowData structure in DOS.
  497. ;
  498. push di
  499. push dx
  500. mov di, es:[bx+6ah] ;kernel data pointer
  501. mov pDosWowData.off, di
  502. mov pDosWowData.sel, es
  503. mov ax, word ptr es:[di].DWD_lpCurPDB
  504. ; mov dx, word ptr es:[di].DWD_lpCurPDB+2
  505. mov pPMDosPDB.off,ax
  506. mov pPMDosPDB.sel,0 ;to force gpfault if not ready
  507. mov ax, word ptr es:[di].DWD_lpCurDrv
  508. ; mov dx, word ptr es:[di].DWD_lpCurDrv+2
  509. mov pPMDosCURDRV.off,ax
  510. mov pPMDosCURDRV.sel,0 ;to force gpfault if not ready
  511. mov ax, word ptr es:[di].DWD_lpCDSCount
  512. ; mov dx, word ptr es:[di].DWD_lpCDSCount+2
  513. mov pPMDosCDSCNT.off,ax
  514. mov pPMDosCDSCNT.sel,0 ;to force gpfault if not ready
  515. mov ax, word ptr es:[di].DWD_lpExterr
  516. mov pPMDosExterr.off, ax
  517. mov pPMDosExtErr.sel, 0
  518. mov ax, word ptr es:[di].DWD_lpExterrLocus
  519. mov pPMDosExterrLocus.off, ax
  520. mov pPMDosExtErrLocus.sel, 0
  521. mov ax, word ptr es:[di].DWD_lpExterrActionClass
  522. mov pPMDosExterrActionClass.off, ax
  523. mov pPMDosExtErrActionClass.sel, 0
  524. pop dx
  525. pop di
  526. lea bx,[bx+sftHead]
  527. mov pFileTable.off,bx
  528. mov pFileTable.sel,es
  529. pop es
  530. endif ; WOW
  531. ife ROM
  532. BootTrace 'b'
  533. call SwitchToPMODE ; BX -> LDT, DS -> CS(DS), SI start of memory
  534. BootTrace 'c'
  535. endif
  536. ReSetKernelDS
  537. mov BaseDsc,si
  538. call LDT_Init
  539. BootTrace 'd'
  540. ifdef WOW
  541. call AllocSelector_0x47
  542. call WOWFastBopInit
  543. endif
  544. if SDEBUG
  545. ; In protected mode, initialize the debugger interface NOW. Only real mode
  546. ; needs to wait until the global heap is initialized.
  547. cCall DebugInit
  548. ; In protected mode, define where our temp Code & Data segments are
  549. mov ax,codeOffset szModName
  550. cCall DebugDefineSegment,<cs,ax,0,cs,0,0>
  551. mov ax,codeOffset szModName
  552. cCall DebugDefineSegment,<cs,ax,3,ds,0,1>
  553. endif
  554. BootTrace 'e'
  555. if ROM
  556. ; In the ROM version, the DS selector doesn't change from now on, so we
  557. ; can tell the debugger where the special kernel data is now.
  558. cCall DebugDebug
  559. endif
  560. BootTrace 'f'
  561. ifdef WOW
  562. push ax
  563. push bx
  564. mov bx, pDosWowData.sel ;use this segment
  565. mov ax, 2
  566. int 31h
  567. mov pPMDosPDB.sel,ax ;make this a PM pointer
  568. mov pPMDosCURDRV.sel,ax ;make this a PM pointer
  569. mov pPMDosCDSCNT.sel,ax ;make this a PM pointer
  570. mov pPMDosExterr.sel,ax
  571. mov pPMDosExterrLocus.sel,ax
  572. mov pPMDosExterrActionClass.sel,ax
  573. pop bx
  574. pop ax
  575. push pDosWowData.sel
  576. push pDosWowData.off
  577. call WOWDosWowInit
  578. endif
  579. ; InitDosVarP just records a few variables, it does no hooking.
  580. ; It does dos version checking and other fun stuff that
  581. ; must be done as soon as possible.
  582. call InitDosVarP
  583. or ax,ax
  584. jnz inited_ok
  585. Debug_Out "KERNEL: InitDosVarP failed"
  586. mov ax,4CFFh ; Goodbye!
  587. INT21
  588. inited_ok:
  589. BootTrace 'g'
  590. push bx
  591. mov bx, WinFlags
  592. ifndef JAPAN ; should be removed because of IBM dependent code.
  593. ifndef NEC_98
  594. ; InitFwdRef routine will set 80x87 status bit in WinFlags
  595. ; and exported location #178.
  596. ; Determine if there is a co-processor present.
  597. int 11h ; get equipment word
  598. test al,2 ; this is the IBM approved method
  599. jz no_80x87 ; to check for an 8087
  600. or bh,WF1_80x87
  601. no_80x87:
  602. endif ; NEC_98
  603. endif ;NOT JAPAN
  604. ifdef WOW
  605. or bh,WF1_WINNT ; Set NT flag ON
  606. endif
  607. mov WinFlags,bx
  608. pop bx
  609. ; Determine if running under Windows/386 or the 286 DOS Extender
  610. push bx
  611. mov ax,(MultWin386 SHL 8) OR MW3_ReqInstall ; Win/386 install check
  612. int 2Fh
  613. BootTrace 'h'
  614. cmp al,MW3_ReqInstall_Ret_4 ; Under WIN386 in pmode?
  615. ifdef WOW ; For WOW Enhanced Mode on 386
  616. ife PMODE32
  617. jnz NotUnderWin386
  618. endif
  619. endif
  620. or Kernel_flags[1],kf1_Win386
  621. or byte ptr WinFlags,WF_PMODE or WF_ENHANCED
  622. jmps InstallChkDone
  623. NotUnderWin386:
  624. or Kernel_flags[2],KF2_DOSX
  625. or byte ptr WinFlags,WF_PMODE or WF_STANDARD
  626. InstallChkDone:
  627. BootTrace 'i'
  628. pop bx
  629. ifndef WOW
  630. ; WOW doesn't muck with the WOAName buffer -- we just leave it
  631. ; as WINOLDAP.MOD
  632. push cx
  633. push di
  634. push si
  635. cld
  636. mov cx,8
  637. smov es,ds
  638. mov di,dataOffset WOAName
  639. mov si,dataOffset woa_286
  640. test Kernel_flags[2],KF2_DOSX
  641. jnz @F
  642. mov si,dataOffset woa_386
  643. @@: rep movsb
  644. pop si
  645. pop di
  646. pop cx
  647. endif
  648. BootTrace 'j'
  649. ife ROM ;--------------------------------------------------------
  650. mov ax,cx
  651. mov cl,4
  652. shr ax,cl
  653. mov cpShrunk,ax
  654. ; Compute paragraph address of new EXE header from SS:SP
  655. mov bx,sp ; SS:SP -> new EXE header
  656. cCall get_physical_address,<ss>
  657. add ax,bx
  658. adc dx,0
  659. BootTrace 'k'
  660. if PMODE32
  661. cCall alloc_data_sel,<dx,ax,0,0FFFFh>
  662. else
  663. cCall alloc_data_sel,<dx,ax,1000h>
  664. endif
  665. BootTrace 'l'
  666. else ; ROM ---------------------------------------------------------
  667. ; Setup selector to ROM Table of Contents
  668. mov ax,word ptr [MyLmaROMTOC]
  669. mov dx,word ptr [MyLmaROMTOC+2]
  670. cCall alloc_data_sel16,<dx,ax,1000h>
  671. if PMODE32
  672. cCall HocusROMBase, <ax>
  673. endif
  674. mov selROMTOC,ax
  675. ; Setup another selector to the ROM prototype LDT
  676. mov es,ax
  677. assumes es,nothing
  678. mov ax,word ptr es:[lmaROMLDT]
  679. mov dx,word ptr es:[lmaROMLDT+2]
  680. cCall alloc_data_sel16,<dx,ax,1000h>
  681. if PMODE32
  682. cCall HocusROMBase, <ax>
  683. endif
  684. mov selROMLDT,ax
  685. mov ax,es:[FirstROMsel]
  686. shr ax,3
  687. add ax,es:[cROMsels]
  688. shl ax,3 ; ax = 1st non-ROM selector
  689. mov sel1stAvail,ax
  690. ; Setup selector to KERNEL EXE header in ROM. **ASSUMES KERNEL is 1st
  691. ; module in ROM TOC**
  692. mov ax,word ptr es:[ModEntries+lmaExeHdr]
  693. mov dx,word ptr es:[ModEntries+lmaExeHdr+2]
  694. cCall alloc_data_sel16,<dx,ax,1000h>
  695. if PMODE32
  696. cCall HocusROMBase, <ax>
  697. endif
  698. endif ; ROM ---------------------------------------------------------
  699. mov segLoadBlock,ax ; hinitexe:0 -> new EXE header
  700. ; calculate the TDB bias
  701. mov bx,dataOffset boottdb
  702. mov initTDBbias,bx
  703. ; calculate the SS bias
  704. mov bx,dataOffset stackbottom
  705. mov initSSbias,bx
  706. ; calculate the initial SP
  707. mov si,dataOffset stacktop
  708. sub si,dataOffset stackbottom
  709. mov initSP,si
  710. cCall get_physical_address,<ds>
  711. add ax,bx
  712. adc dx,0
  713. BootTrace 'm'
  714. if ROM
  715. cCall alloc_data_sel16,<dx,ax,1000h>
  716. FCLI
  717. else
  718. FCLI
  719. mov prev_gmove_SS, ss ; Switch stack while we set up new SS
  720. smov ss, ds
  721. mov sp, dataOFFSET gmove_stack
  722. cCall set_physical_address,<prev_gmove_SS>
  723. xor ax, ax
  724. xchg ax, prev_gmove_SS
  725. endif
  726. BootTrace 'n'
  727. mov ss,ax ; switch to new stack
  728. mov sp,si
  729. FSTI
  730. xor bp,bp ; zero terminate BP chain.
  731. sub si,BOOTSTACKSIZE
  732. mov ss:[pStackBot],sp
  733. mov ss:[pStackMin],sp
  734. mov ss:[pStackTop],si
  735. cld
  736. mov es,topPDB
  737. externB szNoGlobalInit
  738. if ROM ;----------------------------------------------------------------
  739. ; In the ROM Windows version, the "allocated" block in the global heap is
  740. ; the kernel data segment, not the code segments
  741. mov bx,ds ; kernel DS is first busy block
  742. lsl bx,bx ; pass its size to GlobalInit
  743. inc bx
  744. cCall GlobalInit,<MASTER_OBJECT_SIZE,bx,BaseDsc,es:[PDB_block_len]>
  745. jnc mem_init_ok
  746. if KDEBUG
  747. Debug_Out "GlobalInit failed!"
  748. else
  749. mov dx, codeoffset szNoGlobalInit
  750. smov ds, cs
  751. mov ah, 9
  752. int 21h ; Whine
  753. mov ax, 4CFFh
  754. int 21h ; And exit
  755. ;NoGlobalInit db "KERNEL: Unable to initialise heap",13,10,'$'
  756. endif
  757. mem_init_ok:
  758. if KDEBUG
  759. cCall CheckGlobalHeap
  760. endif
  761. else ;ROM ---------------------------------------------------------
  762. BootTrace 'o'
  763. mov ax, BaseDsc ; Free memory starts after this
  764. mov bx,segLoadBlock ; Make boot image be first busy block
  765. mov cx,es:[PDB_block_len] ; cx is end of memory
  766. mov dx,MASTER_OBJECT_SIZE
  767. cCall GlobalInit,<dx,bx,ax,cx>
  768. jc @F ; passed through from ginit
  769. or ax,ax
  770. jnz mem_init_ok
  771. @@:
  772. mov dx, codeoffset szNoGlobalInit
  773. smov ds, cs
  774. mov ah, 9
  775. int 21h ; Whine
  776. mov ax, 4CFFh
  777. int 21h ; And exit
  778. ;NoGlobalInit db "KERNEL: Unable to initialise heap",13,10,'$'
  779. mem_init_ok:
  780. mov hLoadBlock,ax ; Save handle to first busy block
  781. endif ;ROM ---------------------------------------------------------
  782. BootTrace 'p'
  783. mov pExitProc.sel,cs
  784. mov pExitProc.off,codeOffset ExitKernel
  785. ; Find out where we live, and where win.com lives.
  786. mov ds,topPDB
  787. UnSetKernelDS
  788. mov bx,ds
  789. mov ds,ds:[PDB_environ]
  790. xor si,si
  791. cld
  792. envloop1:
  793. lodsb
  794. or al,al ; end of item?
  795. jnz envloop1
  796. lodsb
  797. or al,al ; end of environment?
  798. jnz envloop1
  799. lodsw ; ignore argc, DS:SI -> kernel path
  800. ifdef WOW
  801. smov es, ds ; now ES:SI -> kernel path
  802. else
  803. call get_windir ; on return, DS:DI -> windir= value
  804. smov es,ds
  805. ; Record where to find the 'windows' directory.
  806. BootTrace 'q'
  807. SetKernelDS
  808. or di,di
  809. jz no_win_dir_yet
  810. mov lpWindowsDir.sel,es
  811. mov lpWindowsDir.off,di
  812. mov cBytesWinDir,cx
  813. ; Now set pointer to WIN.INI to be
  814. ; in the Windows directory
  815. push si
  816. push es
  817. smov es, ds
  818. mov si, dataoffset szUserPro+6
  819. mov di, si
  820. inc cx
  821. add di, cx ; Move up the string WIN.INI
  822. std
  823. mov cx, 4
  824. rep movsw
  825. ; Now copy Windows directory
  826. cld
  827. mov cx, cBytesWinDir
  828. mov di, dataoffset szUserPro
  829. lds si, lpWindowsDir
  830. UnSetKernelDS
  831. rep movsb
  832. mov byte ptr es:[di], '\'
  833. pop es
  834. pop si
  835. endif
  836. SetKernelDS
  837. BootTrace 'r'
  838. no_win_dir_yet:
  839. if ROM ;----------------------------------------------------------------
  840. ; 'Load' the kernel exe header from ROM.
  841. mov si,dataOffset ROMKRNL
  842. cCall LKExeHeader,<segLoadBlock,ds,si>
  843. or ax,ax
  844. jnz hdr_ok
  845. jmp bootfail
  846. hdr_ok:
  847. else ;ROM ---------------------------------------------------------
  848. sub sp,SIZE OPENSTRUC + 127
  849. mov di,sp
  850. regptr ssdi,ss,di
  851. mov bx,OF_EXIST
  852. cCall IOpenFile,<essi,ssdi,bx>
  853. BootTrace 's'
  854. inc ax ; Test for -1
  855. jnz opn1 ; Continue if success
  856. mov dx, codeoffset NoOpenFile
  857. fail1:
  858. push dx ; Save string pointer
  859. call textmode ; Switch to text mode
  860. pop dx
  861. smov ds, cs
  862. mov ah, 9
  863. int 21h ; Tell user why we're bailing out
  864. mov ax,4CFFh ; Goodbye!
  865. INT21
  866. opn1:
  867. ; Now simulate loading ourselves from memory
  868. ; Load new EXE header for KERNEL.EXE from memory
  869. cCall LKExeHeader,<segLoadBlock,ssdi>
  870. BootTrace 't'
  871. add sp,SIZE OPENSTRUC + 127
  872. or ax,ax
  873. jnz @F
  874. mov dx, codeoffset NoLoadHeader
  875. jmp SHORT fail1
  876. @@:
  877. endif ;ROM ---------------------------------------------------------
  878. mov hExeHead,ax
  879. mov es,ax
  880. ifndef WOW
  881. ; Record where to find the 'system' directory.
  882. if ROM ;----------------------------------------------------------------
  883. push es
  884. mov es,selROMTOC ; ROM system dir @ selROMTOC:offSysDir
  885. mov di,es:offSysDir
  886. mov lpSystemDir.sel,es
  887. mov lpSystemDir.off,di
  888. xor ax,ax
  889. mov cx,-1
  890. cld
  891. repne scasb
  892. not cx
  893. dec cx
  894. mov cBytesSysDir,cx
  895. pop es
  896. else ;ROM ---------------------------------------------------------
  897. mov di,es:[ne_pfileinfo]
  898. lea di,es:[di].opFile
  899. mov lpSystemDir.sel,es
  900. mov lpSystemDir.off,di
  901. mov dx,di
  902. call GetPureName
  903. sub di,dx
  904. dec di
  905. mov cBytesSysDir,di
  906. endif ;ROM ---------------------------------------------------------
  907. BootTrace 'u'
  908. endif
  909. ; ndef WOW
  910. ; Make room at end of kernel data segment for stack--NOTE: DGROUP is
  911. ; assumed to be segment 4!
  912. mov bx,es:[ne_segtab]
  913. ife ROM
  914. add es:[bx+(3*size NEW_SEG1)].ns_minalloc,EXTRASTACKSIZE
  915. endif
  916. ; Determine size of kernel's largest discardable code segment
  917. ; don't bother with swap area's anymore. Its fixed 192k (3segs)
  918. ; picked this up from Win95
  919. xor ax,ax ; No max
  920. mov es:[ne_swaparea],ax
  921. BootTrace 'v'
  922. ife ROM ;----------------------------------------------------------------
  923. ; Allocate memory for kernel segments
  924. cCall LKAllocSegs,<es>
  925. mov oNRSeg,ax
  926. mov oMSeg, bx ; Misc segment
  927. mov es,hExeHead
  928. ; If this is a pMode debug version, the code and data segments have already
  929. ; been defined to the debugger once. We're about to LoadSegment and define
  930. ; these segments again in their final location. Use a special form of
  931. ; DebugFreeSegment to force the debugger to pull out any breakpoints in these
  932. ; segments. If we don't do this, any existing breakpoints become INT 3's
  933. ; in the new copy of the segment and the code has to be patched by hand.
  934. ; If only the debugger was smart enough to 'move' the breakpoints when it
  935. ; saw a second define for an already loaded segment...
  936. if SDEBUG
  937. cCall DebugFreeSegment,<cs,-1>
  938. cCall DebugFreeSegment,<MyCSDS,-1>
  939. endif
  940. ; Load kernel code segment 1 (resident code)
  941. mov si,1
  942. mov ax,-1 ; Indicate loading from memory
  943. cCall LoadSegment,<es,si,cs,ax>
  944. or ax,ax
  945. jnz ll1
  946. fail2: jmp bootfail
  947. ll1:
  948. mov segNewCS,ax ; Save new CS value
  949. ; Load kernel data segment (segment 4)
  950. mov si,4
  951. mov ax,-1
  952. cCall LoadSegment,<hExeHead,si,ds,ax>
  953. or ax,ax
  954. jz fail2
  955. BootTrace 'w'
  956. ; locate the stack in the new segment
  957. mov bx,ax
  958. mov si,initSP
  959. add si,EXTRASTACKSIZE
  960. else ;ROM ---------------------------------------------------------
  961. cCall SetOwner,<ds,hExeHead> ;Who owns ya baby?
  962. cCall SetROMOwner,<cs,hExeHead> ;IGROUP isn't loaded, but needs owner
  963. ; locate the stack at the end of the data segment
  964. mov ax, ds
  965. mov bx, ax
  966. mov si, initSP
  967. add si, ROMEXTRASTACKSZ
  968. endif ;ROM ---------------------------------------------------------
  969. cCall get_physical_address,<ax>
  970. add ax,initSSbias
  971. adc dx,0
  972. sub ax,10h
  973. sbb dx,0
  974. or ax,10h
  975. FCLI
  976. mov prev_gmove_SS, ss ; Switch stack while we set up new SS
  977. smov ss, ds
  978. mov sp, OFFSET gmove_stack
  979. cCall set_physical_address,<prev_gmove_SS>
  980. push bx
  981. mov bx, si
  982. xor cx, cx ; cx:bx=stack len (for set_sel_limit)
  983. cCall set_sel_limit,<prev_gmove_SS>
  984. pop bx
  985. xor ax, ax
  986. xchg ax, prev_gmove_SS
  987. mov ss,ax ; Switch to new stack location
  988. mov sp,si
  989. FSTI
  990. mov ax,bx
  991. ; zero the new TDB
  992. push ax
  993. cCall get_physical_address,<ax>
  994. add ax,initTDBbias
  995. adc dx,0
  996. if PMODE32
  997. YAH_WELL = (SIZE TDB+15) and NOT 15
  998. cCall alloc_data_sel,<dx,ax,0,YAH_WELL>
  999. else
  1000. YAH_WELL = (SIZE TDB+15)/16
  1001. cCall alloc_data_sel,<dx,ax,YAH_WELL>
  1002. endif
  1003. mov es,ax
  1004. xor ax,ax
  1005. mov di,ax
  1006. mov cx,SIZE TDB
  1007. cld
  1008. rep stosb
  1009. pop ax
  1010. ; put the limits in the stack
  1011. xor bp,bp ; zero terminate BP chain.
  1012. mov ss:[pStackBot],sp
  1013. mov ss:[pStackMin],sp
  1014. mov ss:[pStackTop],10h
  1015. mov ss:[0],bp ; To mark this stack as NOT linked
  1016. mov ss:[2],bp ; to another, see PatchStack.
  1017. mov ss:[4],bp
  1018. ; initialize the new TDB
  1019. sub sp,SIZE TASK_REGS
  1020. mov es:[TDB_taskSS],ss
  1021. mov es:[TDB_taskSP],sp
  1022. mov cx,topPDB
  1023. mov es:[TDB_PDB],cx ; save new PDB
  1024. mov es:[TDB_DTA].off,80h ; set initial DTA
  1025. mov es:[TDB_DTA].sel,cx
  1026. mov bx,1 ; BX = 1
  1027. mov es:[TDB_nEvents],bx ; Start this guy up!
  1028. mov es:[TDB_pModule],-1 ; EMS requires -1
  1029. mov bx,winVer
  1030. mov es:[TDB_ExpWinVer],bx ; Windows Version #
  1031. mov es:[TDB_sig],TDB_SIGNATURE ; Set signature word.
  1032. ; initialize the task BP and DS
  1033. push es
  1034. les bx,dword ptr es:[TDB_taskSP]
  1035. mov es:[bx].TASK_BP,bp ; initial BP = 0
  1036. mov es:[bx].TASK_DS,bp ; initial DS = 0
  1037. pop es
  1038. ife ROM ;---------------------------------------------------------------
  1039. mov ds,ax ; switch to new DS segment
  1040. mov ax,segNewCS ; recover new CS value
  1041. push cs ; to free the selector
  1042. ; do a far return to the new code segment
  1043. push ax
  1044. mov ax,codeOffset new_code
  1045. push ax
  1046. ret_far ; FAR return to new code segment
  1047. public new_code
  1048. new_code:
  1049. pop ax
  1050. push es
  1051. cCall free_sel,<ax> ; Free old CS selector
  1052. cCall IPrestoChangoSelector,<cs,MyCSAlias> ; Change our CS Alias
  1053. mov es,MyCSAlias ; Change MyCSDS to new DS
  1054. assumes es,CODE
  1055. mov ax,ds
  1056. xchg ax,es:MyCSDS
  1057. assumes es,nothing
  1058. cCall free_sel,<ax> ; Free old DS selector
  1059. call DebugDebug ; do after MyCSDS changes
  1060. mov pExitProc.sel,cs ; reset this!!
  1061. ;;; pusha
  1062. ;;; cCall get_physical_address,<cs>
  1063. ;;; add ax, codeOffset end_page_locked
  1064. ;;; adc dx, 0
  1065. ;;; mov bx, dx
  1066. ;;; mov cx, ax
  1067. ;;; mov di, cs
  1068. ;;; lsl di, di
  1069. ;;; sub di, codeOffset end_page_locked
  1070. ;;; xor si, si
  1071. ;;; mov ax, 0601h
  1072. ;;; int 31h ; Unlock some of Kernel!
  1073. ;;; popa
  1074. cCall SelToSeg,<ds> ; Save DS segment value
  1075. mov MyDSSeg,ax
  1076. cCall SelToSeg,<cs> ; Set segment equivalent
  1077. mov MyCSSeg, ax
  1078. ; calculate the maximum amount that we will allow SetSwapAreaSize to set
  1079. mov ax,-1 ; They can only harm themselves.
  1080. else ;ROM ---------------------------------------------------------
  1081. push es ; code below expects this on stack
  1082. mov ax,-1 ; They can only harm themselves.
  1083. endif ;ROM ---------------------------------------------------------
  1084. mov MaxCodeSwapArea,ax
  1085. ifndef WOW ; WOW uses 32 bit profile api's
  1086. ; Allocate a handle for WIN.INI
  1087. xor ax,ax
  1088. mov bx,GA_SHAREABLE shl 8 OR GA_MOVEABLE
  1089. cCall IGlobalAlloc,<bx,ax,ax>
  1090. mov [WinIniInfo.hBuffer], ax
  1091. or ax,ax
  1092. jz nowinini
  1093. mov bx,ax ; put handle into base register
  1094. mov ax,hExeHead
  1095. mov es,ax
  1096. call set_discarded_sel_owner
  1097. ; Set up the filename
  1098. mov word ptr [WinIniInfo.lpProFile], dataoffset szUserPro
  1099. mov word ptr [WinIniInfo.lpProFile][2], ds
  1100. nowinini:
  1101. ; Allocate a handle for Private Profiles
  1102. xor ax,ax
  1103. mov bx,GA_SHAREABLE shl 8 OR GA_MOVEABLE
  1104. cCall IGlobalAlloc,<bx,ax,ax>
  1105. mov [PrivateProInfo.hBuffer],ax
  1106. or ax,ax
  1107. jz noprivate
  1108. mov bx,ax ; put handle into base register
  1109. mov ax,hExeHead
  1110. mov es,ax
  1111. call set_discarded_sel_owner
  1112. noprivate:
  1113. endif; WOW
  1114. ifdef WOW
  1115. ; Allocate a ~128K discardable code selector to hide the
  1116. ; GrowHeap - heap not sorted bugs, also present in Win 3.1.
  1117. ;
  1118. ; Since our system DLLs (like krnl386, user, gdi etc) contain a few
  1119. ; discardable codesgements (of approx 40K), we need not be precise
  1120. ;
  1121. push es
  1122. mov ax, 0C000H ; hiword is 01h , totalsize 0x1c000 bytes
  1123. mov bx, GA_MOVEABLE OR GA_DISCCODE
  1124. cCall IGlobalAlloc,<bx,01h,ax>
  1125. or ax,ax
  1126. jz short nogrowheap
  1127. cCall SetOwner, <ax, hExeHead>
  1128. nogrowheap:
  1129. pop es
  1130. endif; WOW
  1131. ife ROM ;----------------------------------------------------------------
  1132. ; Now shrink off exe header and segment 1 of KERNEL.EXE
  1133. mov si,2 ; Segment number
  1134. xor ax,ax
  1135. xchg oNRSeg,ax
  1136. nofastboot:
  1137. sub ax,cpShrunk
  1138. mov cpShrink,ax ; Amount to shrink by
  1139. cCall MyLock,<hLoadBlock>
  1140. mov bx,ax
  1141. xchg segLoadBlock,ax
  1142. cCall get_physical_address,<ax>
  1143. mov cx,dx
  1144. xchg bx,ax
  1145. cCall get_physical_address,<ax>
  1146. sub bx,ax
  1147. sbb cx,dx
  1148. REPT 4
  1149. shr cx,1
  1150. rcr bx,1
  1151. ENDM
  1152. mov ax,bx
  1153. add cpShrink,ax
  1154. push ax
  1155. cCall Shrink
  1156. pop ax
  1157. sub cpShrunk,ax
  1158. ; Load kernel code segment 2 (non-resident code)
  1159. cCall MyLock,<hLoadBlock>
  1160. mov bx,-1 ; Indicate loading from memory
  1161. cCall LoadSegment,<hExeHead,si,ax,bx>
  1162. or ax,ax
  1163. jnz ll2
  1164. pop es
  1165. jmp bootfail
  1166. ll2:
  1167. inc si ; On to segment 3
  1168. xor ax, ax
  1169. xchg ax, oMSeg ; Once back only!
  1170. or ax, ax
  1171. jnz nofastboot
  1172. else ;ROM ---------------------------------------------------------
  1173. ; The ROM kernel 'loads' the other two kernel segments now. Currently
  1174. ; LoadSegment does little more than define the segment to the debugger
  1175. ; which has already been done for the primary code & data segments.
  1176. cCall LoadSegment,<hExeHead,2,0,-1>
  1177. cCall SetROMOwner,<ax,hExeHead>
  1178. cCall LoadSegment,<hExeHead,3,0,-1>
  1179. cCall SetROMOwner,<ax,hExeHead>
  1180. endif ;ROM ---------------------------------------------------------
  1181. pop es
  1182. call genter
  1183. smov ds, es
  1184. UnSetKernelDS
  1185. SetKernelDS es
  1186. ;;;mov ax,EMScurPID ; In case an EMS fast boot is going down.
  1187. ;;;mov ds:[TDB_EMSPID],ax
  1188. ;;;mov ax,ds:[TDB_EMSPID]
  1189. ;;;mov PID_for_fake,ax
  1190. ;;;mov EMScurPID,ax
  1191. mov curTDB,ds
  1192. mov headTDB,ds
  1193. push es
  1194. ; vectors
  1195. SaveVec MACRO vec
  1196. mov ax, 35&vec
  1197. DOSCALL
  1198. mov [di.off], bx
  1199. mov [di.sel], es
  1200. add di, 4
  1201. ENDM
  1202. push di
  1203. mov di, TDB_INTVECS
  1204. SaveVec 00h
  1205. SaveVec 02h
  1206. SaveVec 04h
  1207. SaveVec 06h
  1208. SaveVec 07h
  1209. SaveVec 3Eh
  1210. SaveVec 75h
  1211. ifdef WOW
  1212. ;; Hook Int10 so we can filter calls in WOW (see intnn.asm)
  1213. push es
  1214. push ds
  1215. mov ax,3510h
  1216. INT21
  1217. mov ax,codeOffset prevInt10proc
  1218. SetKernelCSDword ax,es,bx
  1219. mov ax,2510h
  1220. smov ds,cs
  1221. mov dx,codeOFFSET Int10Handler
  1222. INT21
  1223. pop ds
  1224. pop es
  1225. endif
  1226. pop di
  1227. cCall SaveState,<ds>
  1228. pop es
  1229. mov ds,pGlobalHeap
  1230. call gleave
  1231. UnSetKernelDS es
  1232. mov ax, 32 ; Kernel wants a big handle table
  1233. cCall SetHandleCount,<ax>
  1234. SetKernelDS
  1235. ;
  1236. ; The following variable initialization is done here to avoid having
  1237. ; relocations in Kernel's data segment.
  1238. ;
  1239. mov lpInt21.off,codeOFFSET Int21Handler
  1240. mov lpInt21.sel,cs
  1241. ;
  1242. ; Before we hook exception handlers, make sure the DPMI exception
  1243. ; handler stack is set up the way Windows likes it.
  1244. ;
  1245. mov bl,6
  1246. mov ax,0202h ; DPMI get exception handler vector
  1247. int 31h
  1248. push cx
  1249. push dx
  1250. mov cx,cs
  1251. lea dx,fixing_stack
  1252. mov bl,6
  1253. mov ax,0203h ; DPMI set exception handler vector
  1254. int 31h
  1255. pop dx
  1256. pop cx
  1257. ;
  1258. ; Generate an invalid opcode exception fault. This causes DPMI to call
  1259. ; our "exception handler."
  1260. ;
  1261. db 0fh,0ffh
  1262. fixing_stack:
  1263. push bp
  1264. mov bp,sp ; BP -> BP RETIP RETCS EC IP CS FL SP SS
  1265. ;
  1266. ; Restore the previous invalid exception handler vector.
  1267. ;
  1268. mov bl,6
  1269. mov ax,0203h
  1270. int 31h
  1271. ;
  1272. ; Replace the return address on the DPMI fault handler routine with
  1273. ; our exit code.
  1274. ;
  1275. lea ax,done_fixing_stack
  1276. mov [bp+8],ax
  1277. mov [bp+10],cs
  1278. lea ax,[bp+16]
  1279. mov ss:[pStackBot],ax
  1280. mov ss:[pStackMin],sp
  1281. mov ss:[pStackTop],offset pStackBot + 150
  1282. mov sp,bp
  1283. pop bp
  1284. retf
  1285. done_fixing_stack:
  1286. ife ROM
  1287. mov es, MyCSAlias
  1288. assumes es, CODE
  1289. endif
  1290. ; Hook not present fault for segment reloader.
  1291. mov ax,0202h ; Record old not present fault.
  1292. mov bl,0Bh
  1293. int 31h
  1294. mov prevInt3Fproc.off,dx
  1295. mov prevInt3Fproc.sel,cx
  1296. mov ax,0203h ; Hook not present fault.
  1297. mov cx,cs
  1298. mov dx,codeOffset SegmentNotPresentFault
  1299. int 31h
  1300. ; Hook GP fault in order to terminate app.
  1301. mov bl, 0Dh ; GP Fault
  1302. mov ax, 0202h
  1303. int 31h
  1304. mov prevInt0Dproc.off, dx
  1305. mov prevInt0Dproc.sel, cx
  1306. mov ax, 0203h
  1307. mov cx, cs
  1308. mov dx, codeOffset GPFault
  1309. int 31h
  1310. ; Hook invalid op-code in order to terminate app.
  1311. mov bl, 06h ; invalid op-code
  1312. mov ax, 0202h
  1313. int 31h
  1314. mov prevIntx6proc.off, dx
  1315. mov prevIntx6proc.sel, cx
  1316. mov ax, 0203h
  1317. mov cx, cs
  1318. mov dx, codeOffset invalid_op_code_exception
  1319. int 31h
  1320. ; Hook stack fault in order to terminate app.
  1321. mov bl, 0Ch ; stack fault
  1322. mov ax, 0202h
  1323. int 31h
  1324. mov prevInt0Cproc.off, dx
  1325. mov prevInt0Cproc.sel, cx
  1326. mov ax, 0203h
  1327. mov cx, cs
  1328. mov dx, codeOffset StackFault
  1329. int 31h
  1330. ; Hook bad page fault in order to terminate app.
  1331. mov bl, 0Eh ; page fault
  1332. mov ax, 0202h
  1333. int 31h
  1334. mov prevInt0Eproc.off, dx
  1335. mov prevInt0Eproc.sel, cx
  1336. mov ax, 0203h
  1337. mov cx, cs
  1338. mov dx, codeOffset page_fault
  1339. int 31h
  1340. ifdef WOW
  1341. ; Hook divide overflow trap in order to get better WOW debugging.
  1342. mov bl, 00h ; divide overflow
  1343. mov ax, 0202h
  1344. int 31h
  1345. mov oldInt00proc.off, dx
  1346. mov oldInt00proc.sel, cx
  1347. mov ax, 0203h
  1348. mov cx, cs
  1349. mov dx, codeOffset divide_overflow
  1350. int 31h
  1351. ; Hook single step trap in order to get better WOW debugging.
  1352. mov bl, 01h ; single step
  1353. mov ax, 0202h
  1354. int 31h
  1355. mov prevInt01proc.off, dx
  1356. mov prevInt01proc.sel, cx
  1357. mov ax, 0203h
  1358. mov cx, cs
  1359. mov dx, codeOffset single_step
  1360. int 31h
  1361. ; Hook breakpoint trap in order to get better WOW debugging.
  1362. mov bl, 03h ; page fault
  1363. mov ax, 0202h
  1364. int 31h
  1365. mov prevInt03proc.off, dx
  1366. mov prevInt03proc.sel, cx
  1367. mov ax, 0203h
  1368. mov cx, cs
  1369. mov dx, codeOffset breakpoint
  1370. int 31h
  1371. endif
  1372. assumes es, nothing
  1373. ; Do a slimy fix-up of __WinFlags containing processor and protect mode flags
  1374. xor ax,ax
  1375. mov dx,178
  1376. cCall GetProcAddress,<hExeHead,ax,dx>
  1377. mov ax,WinFlags
  1378. mov es:[bx],ax
  1379. ifdef WOW
  1380. ; get WOW32 thunk table offsets and do fixups
  1381. ; WARNING: WOW32 has a dependency on this being called after
  1382. ; kernel is done booting and addresses are fixed
  1383. push ds
  1384. push dataoffset MOD_KERNEL
  1385. call far ptr WOWGetTableOffsets
  1386. mov si, dataoffset MOD_KERNEL
  1387. mov cx, ModCount ; # fixups to do
  1388. mov di, 570 ; first ordinal of the group (DANGER hardcoded from kernel.def)
  1389. Mexico:
  1390. push si
  1391. push di
  1392. push cx
  1393. push hExeHead
  1394. push 0
  1395. push di
  1396. call GetProcAddress
  1397. pop cx
  1398. pop di
  1399. pop si
  1400. mov ax,[si]
  1401. mov es:[bx],ax
  1402. inc si ; point to next word
  1403. inc si
  1404. inc di ; get next ordinal
  1405. loop Mexico
  1406. endif
  1407. ife ROM ;--------------------------------
  1408. ; Can't do slimy fix-ups in ROM--already done by ROM Image Builder
  1409. ; Do a very slimy fix-up of the runtime constant __0000h
  1410. cCall GetProcAddress,<hExeHead,0,183>
  1411. mov si,bx
  1412. mov bx,00000h
  1413. mov ax,2
  1414. int 31h
  1415. mov es:[si],ax
  1416. ; Do a very slimy fix-up of the runtime constant __0040h
  1417. cCall GetProcAddress,<hExeHead,0,193>
  1418. mov si,bx
  1419. mov bx,00040h
  1420. mov ax,2
  1421. int 31h
  1422. mov es:[si],ax
  1423. ; Do a very slimy fix-up of the runtime constant __ROMBIOS
  1424. cCall GetProcAddress,<hExeHead,0,173>
  1425. mov si,bx
  1426. mov bx,0F000h
  1427. mov ax,2
  1428. int 31h
  1429. mov es:[si],ax
  1430. ; Do a very slimy fix-up of the runtime constant __F000h
  1431. cCall GetProcAddress,<hExeHead,0,194>
  1432. mov si,bx
  1433. mov bx,0F000h
  1434. mov ax,2
  1435. int 31h
  1436. mov es:[si],ax
  1437. ; Do a very slimy fix-up of the runtime constant __A000h
  1438. cCall GetProcAddress,<hExeHead,0,174>
  1439. mov si,bx
  1440. mov bx,0A000h
  1441. mov ax,2
  1442. int 31h
  1443. mov es:[si],ax
  1444. ; Do a very slimy fix-up of the runtime constant __B000h
  1445. cCall GetProcAddress,<hExeHead,0,181>
  1446. mov si,bx
  1447. mov bx,0B000h
  1448. mov ax,2
  1449. int 31h
  1450. mov es:[si],ax
  1451. ; Do a very slimy fix-up of the runtime constant __B800h
  1452. cCall GetProcAddress,<hExeHead,0,182>
  1453. mov si,bx
  1454. mov bx,0B800h
  1455. mov ax,2
  1456. int 31h
  1457. mov es:[si],ax
  1458. ; Do a very slimy fix-up of the runtime constant __C000h
  1459. cCall GetProcAddress,<hExeHead,0,195>
  1460. mov si,bx
  1461. mov bx,0C000h
  1462. mov ax,2
  1463. int 31h
  1464. mov es:[si],ax
  1465. ; Do a very slimy fix-up of the runtime constant __D000h
  1466. cCall GetProcAddress,<hExeHead,0,179>
  1467. mov si,bx
  1468. mov bx,0D000h
  1469. mov ax,2
  1470. int 31h
  1471. mov es:[si],ax
  1472. ; Do a very slimy fix-up of the runtime constant __E000h
  1473. cCall GetProcAddress,<hExeHead,0,190>
  1474. mov si,bx
  1475. mov bx,0E000h
  1476. mov ax,2
  1477. int 31h
  1478. mov es:[si],ax
  1479. endif ;ROM -------------------------
  1480. ifndef WOW
  1481. cCall SetUserPro ; Get WIN.INI filename from environment
  1482. endif
  1483. CheckKernelDS
  1484. ; Free high memory copy of KERNEL.EXE
  1485. ife ROM
  1486. cCall IGlobalFree,<hLoadBlock>
  1487. mov hLoadBlock,ax
  1488. else
  1489. xor ax, ax
  1490. endif
  1491. if PMODE32
  1492. .386
  1493. mov fs, ax
  1494. mov gs, ax
  1495. .286p
  1496. endif
  1497. ifndef WOW
  1498. cmp lpWindowsDir.sel,ax
  1499. jnz got_win_dir
  1500. mov si,dataOffset szUserPro
  1501. mov di,dataOffset [WinIniInfo.ProBuf]
  1502. cCall IOpenFile,<dssi,dsdi,OF_PARSE>
  1503. lea di,[di].opfile
  1504. mov lpWindowsDir.sel,ds
  1505. mov lpWindowsDir.off,di
  1506. mov dx,di
  1507. call GetPureName
  1508. sub di,dx
  1509. dec di
  1510. mov cBytesWinDir,di
  1511. got_win_dir:
  1512. endif
  1513. ifdef WOW
  1514. ; Regular Windows kernel sets up the Windows directory very early in
  1515. ; boot, before WOW kernel loads WOW32.DLL.
  1516. ;
  1517. ; It turns out we can delay setting up the 16-bit copy of the
  1518. ; windows directory (referred by lpWindowsDir) until here, where
  1519. ; we're in protected mode and about to set up the system directories
  1520. ; as well. This allows us to call a GetShortPathName thunk in
  1521. ; WOW32.
  1522. ;
  1523. mov ds,topPDB
  1524. UnSetKernelDS
  1525. mov ds,ds:[PDB_environ]
  1526. call get_windir ; on return, DS:DI -> windows dir
  1527. smov es,ds
  1528. SetKernelDS
  1529. ; Record where to find the 'windows' directory.
  1530. BootTrace 'q'
  1531. mov lpWindowsDir.sel,es
  1532. mov lpWindowsDir.off,di
  1533. mov cBytesWinDir,cx
  1534. ; Record where to find the 'system32' directory.
  1535. mov ax,hExeHead
  1536. mov es,ax
  1537. mov di,es:[ne_pfileinfo]
  1538. lea di,es:[di].opFile
  1539. mov lpSystemDir.sel,es
  1540. mov lpSystemDir.off,di
  1541. mov dx,di
  1542. call GetPureName
  1543. sub di,dx
  1544. dec di
  1545. mov cBytesSysDir,di
  1546. BootTrace 'u'
  1547. ;
  1548. ; Under WOW there are two system directories: \nt\system and \nt\system32.
  1549. ; lpSystemDir points to \nt\system32, while lpSystem16Dir points to
  1550. ; \nt\system. We return the latter from GetSystemDirectory, since we want
  1551. ; applications to install their shared stuff in \nt\system, but we want
  1552. ; to search \nt\system32 before \nt\system when loading modules.
  1553. ; Set up lpSystem16Dir using the Windows dir + \system.
  1554. ; Note that the string pointed to by lpSystem16Dir is not null terminated!
  1555. mov lpSystem16Dir.sel,ds
  1556. mov lpSystem16Dir.off,dataoffset achSystem16Dir
  1557. cld
  1558. mov si,dataoffset achRealWindowsDir
  1559. mov es,lpSystem16Dir.sel
  1560. mov di,lpSystem16Dir.off
  1561. mov cx,cbRealWindowsDir
  1562. rep movsb ; copy Windows dir
  1563. mov si,dataoffset Sys16Suffix
  1564. mov cx,cBytesSys16Suffix
  1565. rep movsb ; tack on "\system"
  1566. mov cx,cbRealWindowsDir
  1567. add cx,cBytesSys16Suffix
  1568. mov cBytesSys16Dir,cx
  1569. ;
  1570. ; build the Wx86 system directory "Windir\Sys32x86"
  1571. ;
  1572. mov lpSystemWx86Dir.sel,ds
  1573. mov lpSystemWx86Dir.off,dataoffset achSystemWx86Dir
  1574. mov es,lpSystemWx86Dir.sel
  1575. mov di,lpSystemWx86Dir.off
  1576. mov cx,cbRealWindowsDir
  1577. mov si,dataoffset achRealWindowsDir
  1578. rep movsb ; copy System dir (Windows\System32)
  1579. mov si,dataoffset SysWx86Suffix
  1580. mov cx,cBytesSysWx86Suffix
  1581. rep movsb ; tack on "\Wx86"
  1582. mov cx,cbRealWindowsDir
  1583. add cx,cBytesSysWx86Suffix
  1584. mov cBytesSysWx86Dir,cx
  1585. @@:
  1586. ; WOW DPMI Supports wants to call GlobalDosAlloc and GlobalDosFree so that
  1587. ; We don't have to write the same code for DPMI support. So we call DPMI
  1588. ; Here with the addresses of those routines so he can call us back.
  1589. mov bx,cs
  1590. mov si,bx
  1591. mov dx,codeOffset GlobalDosAlloc
  1592. mov di,codeOffset GlobalDosFree
  1593. mov ax,4f3h
  1594. int 31h
  1595. ; Now that we've built up the system dir from the windows dir, set
  1596. ; the windows dir to where it should be for this user.
  1597. push es
  1598. cld
  1599. mov di,offset achTermsrvWindowsDir
  1600. cCall TermsrvGetWindowsDir,<ds, di, MaxFileLen>
  1601. or ax, ax
  1602. jz @F ; ax = 0 -> error, just leave windows dir
  1603. smov es,ds
  1604. mov cx,-1
  1605. xor ax,ax
  1606. repnz scasb
  1607. not cx
  1608. dec cx ; length of windows directory
  1609. mov lpWindowsDir.sel,ds
  1610. mov lpWindowsDir.off,offset achTermsrvWindowsDir
  1611. mov cBytesWinDir,cx
  1612. @@:
  1613. pop es
  1614. endif
  1615. ; Under win 2.11 we allowed the ":" syntax to replace the shell.
  1616. ; We no longer allow this, however to avoid messing up people
  1617. ; with batch files that have ":" in them we will strip the
  1618. ; ":" out of the command line. But we retain the :: syntax
  1619. ; for the OS/2 VM!!
  1620. ; We also do the check for the /b switch here. This puts us in "diagnostic
  1621. ; mode and we set a flag to say this. Later, we will call the DiagInit()
  1622. ; function to open the log file, etc.
  1623. push ds
  1624. cld
  1625. mov ds,topPDB
  1626. UnSetKernelDS
  1627. push ds
  1628. pop es
  1629. mov si,80h
  1630. xor ax,ax
  1631. lodsb
  1632. or al,al
  1633. jz no_colon
  1634. mov cx,ax
  1635. @@: lodsb
  1636. cmp al,' '
  1637. loopz @B
  1638. cmp al,':'
  1639. jnz no_colon
  1640. cmp byte ptr [si],':'
  1641. jz no_colon
  1642. mov byte ptr [si][-1],' '
  1643. no_colon:
  1644. cmp al,'/' ;Switch character?
  1645. je CheckSwitch ;Yes
  1646. cmp al,'-' ;Other switch character?
  1647. jne NoSwitch ;Nope.
  1648. CheckSwitch:
  1649. lodsb ;Get next char
  1650. or al,32 ;Convert to lowercase if necessary
  1651. cmp al,'b' ;Diagnostic mode?
  1652. jnz NoSwitch ;Nope
  1653. cCall DiagInit ;Initialize diagnostic mode
  1654. mov WORD PTR [si-2],2020h ;Blank out the switch
  1655. NoSwitch:
  1656. pop ds
  1657. ReSetKernelDS
  1658. ;** Reset secret flag for memory manager. Fixed segments will go
  1659. ;** >1MB after this
  1660. and fBooting, NOT 2
  1661. ;** We want to grow the SFT *before* loading the modules,
  1662. ;** not after, like was the case previous to win3.1
  1663. call GrowSFTToMax ;add to SFT chain in p mode
  1664. if 1
  1665. ; old ldinit.c
  1666. cld
  1667. push ds
  1668. smov es,ds
  1669. xor ax,ax
  1670. xor cx,cx
  1671. mov ds,topPDB
  1672. UnSetKernelDS
  1673. mov si,80h
  1674. lodsb
  1675. or al,al
  1676. jz gwaphics_done
  1677. mov cl,al
  1678. lodsb
  1679. cmp al,' '
  1680. mov al,ah
  1681. jnz gwaphics_done
  1682. lodsb
  1683. cmp al,':'
  1684. mov al,ah
  1685. jnz gwaphics_done
  1686. lodsb
  1687. cmp al,':'
  1688. mov al,ah
  1689. jnz gwaphics_done
  1690. mov di,dataOffset app_name
  1691. find_delineator:
  1692. lodsb
  1693. stosb
  1694. cmp al,' '
  1695. ja find_delineator
  1696. mov es:[di][-1],ah
  1697. mov ds:[80h],ah ; assume no arguments
  1698. jnz gwaphics_done
  1699. add cx,82h
  1700. sub cx,si
  1701. smov es,ds
  1702. mov di,80h
  1703. mov al,cl
  1704. stosb
  1705. rep movsb
  1706. gwaphics_done:
  1707. pop ds
  1708. ReSetKernelDS
  1709. or ax,ax
  1710. jz @F
  1711. mov graphics,0
  1712. @@:
  1713. else
  1714. cld
  1715. xor ax,ax
  1716. xor bx,bx
  1717. endif
  1718. jmps SlowBoot
  1719. bootfail:
  1720. mov al,1
  1721. cCall ExitKernel,<ax>
  1722. cEnd nogen
  1723. sEnd INITCODE
  1724. ;-----------------------------------------------------------------------;
  1725. ; SlowBoot ;
  1726. ; ;
  1727. ; ;
  1728. ; Arguments: ;
  1729. ; ;
  1730. ; Returns: ;
  1731. ; ;
  1732. ; Error Returns: ;
  1733. ; ;
  1734. ; Registers Preserved: ;
  1735. ; ;
  1736. ; Registers Destroyed: ;
  1737. ; ;
  1738. ; Calls: ;
  1739. ; ;
  1740. ; History: ;
  1741. ; ;
  1742. ; Sat Mar 14, 1987 05:52:22p -by- David N. Weise [davidw] ;
  1743. ; Added this nifty comment block. ;
  1744. ;-----------------------------------------------------------------------;
  1745. DataBegin INIT
  1746. BootSect db 'BOOT',0
  1747. BootFile db 'SYSTEM.INI',0
  1748. FilesCached db 'CACHEDFILEHANDLES',0
  1749. IdleSegLoad db 'LOADSEGMENTSATIDLE',0
  1750. ifdef WOW
  1751. ExitLastApp db 'CLOSEONLASTAPPEXIT',0
  1752. endif
  1753. if SHERLOCK
  1754. szGPC db 'GPCONTINUE',0
  1755. endif
  1756. szDebugSect db 'DEBUG',0
  1757. szOutputTo db 'OUTPUTTO', 0
  1758. szAux db 0 ;'AUX', 0 ; don't return a default
  1759. if KDEBUG
  1760. szKRInfo db 'KERNELINFO', 0
  1761. szKRBreak db 'KERNELBREAK', 0
  1762. szWin3Info db 'WIN3INFO', 0
  1763. szWin3Break db 'WIN3BREAK', 0
  1764. endif
  1765. ife PMODE32
  1766. Standard db 'STANDARD',0
  1767. PadCodeStr db 'PADCODESEGMENTS',0
  1768. endif
  1769. BootBufLen equ 80
  1770. BootBuf db BootBufLen dup (?)
  1771. bootmods label byte
  1772. DB 'SYSTEM.DRV',0
  1773. winmods label byte
  1774. ifdef WOW
  1775. DB 'KEYBOARD.DRV',0
  1776. szAfterKeyboardDriver label byte ;Used so we can tell key driver loaded
  1777. DB 'MOUSE.DRV',0
  1778. ifdef FE_SB
  1779. szBeforeWifeMan label byte ;Used so we can tell key driver loaded
  1780. DB 'WIFEMAN.DLL', 0 ;WIFE manager has to be loaded before display driver
  1781. endif
  1782. DB 'VGA.DRV',0
  1783. DB 'SOUND.DRV',0
  1784. DB 'COMM.DRV',0
  1785. DB 'USER.EXE',0
  1786. DB 'GDI.EXE',0
  1787. ifdef FE_SB
  1788. szBeforeWinNls label byte ;Used so we can tell key driver loaded
  1789. DB 'WINNLS.DLL', 0 ;bug #112335
  1790. endif
  1791. else
  1792. DB 'KEYBOARD.DRV',0
  1793. szAfterKeyboardDriver label byte ;Used so we can tell key driver loaded
  1794. DB 'MOUSE.DRV',0
  1795. ifdef FE_SB
  1796. szBeforeWifeMan label byte ;Used so we can tell key driver loaded
  1797. DB 'WIFEMAN.DLL', 0 ;WIFE manager has to be loaded before
  1798. ;display driver
  1799. endif
  1800. DB 'DISPLAY.DRV',0
  1801. DB 'SOUND.DRV',0
  1802. DB 'COMM.DRV',0
  1803. DB 'FONTS.FON',0
  1804. DB 'OEMFONTS.FON',0 ; For Internationals use.
  1805. DB 'GDI.EXE',0
  1806. DB 'USER.EXE',0
  1807. ifdef FE_SB
  1808. szBeforeWinNls label byte ;Used so we can tell key driver loaded
  1809. DB 'WINNLS.DLL', 0
  1810. endif
  1811. endif
  1812. ifdef WOW
  1813. defapp label byte
  1814. DB 'WOWEXEC.EXE',0
  1815. else
  1816. defapp label byte
  1817. DB 'PROGMAN.EXE',0
  1818. endif
  1819. Shell label byte
  1820. DB 'WOWSHELL',0
  1821. ;** Ordinal strings for two of the Keyboard driver exports
  1822. keymodstr DB 'KEYBOARD',0
  1823. keyprocstr DB '#5',0 ; keyprocstr = AnsiToOem
  1824. keyprocstr1 DB '#6',0 ; keyprocstr = OemToAnsi
  1825. DataEnd INIT
  1826. sBegin INITCODE
  1827. assumes cs,CODE
  1828. assumes ds,nothing
  1829. assumes es,nothing
  1830. if BootTraceOn
  1831. cProc BootTraceChar,<PUBLIC,NEAR,NODATA>, <ax, dx>
  1832. parmW char
  1833. cBegin
  1834. mov dx, 3fdh
  1835. @@: in al, dx
  1836. test al, 20h
  1837. jz @B
  1838. mov ax, char
  1839. mov dx, 3f8h
  1840. out dx, al
  1841. cEnd
  1842. endif ; BootTraceOn
  1843. cProc ttywrite,<PUBLIC,NEAR,NODATA>, <ds, si>
  1844. parmD s
  1845. cBegin
  1846. ; cCall lstrlen,<s>
  1847. ; mov cx, ax
  1848. ; lds bx, s
  1849. ; mov bx,1
  1850. ; mov ah,40h
  1851. ; int 21h
  1852. lds si, s
  1853. cld
  1854. mov ah, 2
  1855. tty1:
  1856. lodsb
  1857. mov dl, al
  1858. or dl, dl
  1859. jz tty2
  1860. int 21h
  1861. jmps tty1
  1862. tty2:
  1863. cEnd
  1864. ifdef WOW
  1865. cProc LoadFail,<PUBLIC,NEAR,NODATA>, <ds,si,di,cx>
  1866. parmD s
  1867. cBegin
  1868. ;** Put Up a Dialog Box If we can't load a module
  1869. ; since szPleaseDoIt resides in protected cs we can't concat the module
  1870. ; name to it -- so we need to copy it to the stack
  1871. ;szPleaseDoIt db "Please re-install the following module to your system32
  1872. ; directory: ",13,10,9,9,0
  1873. mov di,sp ; save current stack pointer
  1874. sub sp,100h ; allocate for new concat'd string on the stack
  1875. mov si,sp ; save the start of the stack string
  1876. push ss ; copy szPleaseDoIt to the stack buffer
  1877. push si
  1878. push cs
  1879. push codeOFFSET szPleaseDoIt
  1880. call lstrcpy
  1881. push ss ; concat module name to string on stack
  1882. push si
  1883. lds cx, s ; get the module name
  1884. push ds
  1885. push cx
  1886. call lstrcat
  1887. push ss ;push finished stack string now
  1888. push si
  1889. push cs ;szMissingMod db "KERNEL: Missing 16-bit module:",0
  1890. push codeOFFSET szMissingMod ; Set Caption
  1891. push 0 ;No left button
  1892. push SEB_CLOSE + SEB_DEFBUTTON ;Button 1 style
  1893. push 0 ;No right button
  1894. externFP kSYSERRORBOX
  1895. call kSYSERRORBOX ;Put up the system message
  1896. mov sp,di ; restore sp
  1897. cEnd
  1898. else // non-WOW
  1899. cProc LoadFail,<PUBLIC,NEAR,NODATA>, <ds>
  1900. parmD s
  1901. cBegin
  1902. SetKernelDS
  1903. cCall TextMode
  1904. mov bx, dataoffset szCRLF
  1905. cCall ttywrite, dsbx
  1906. mov bx, dataoffset szCRLF
  1907. cCall ttywrite, dsbx
  1908. mov bx, dataoffset szBootLoad
  1909. cCall ttywrite, dsbx
  1910. cCall ttywrite, s
  1911. mov bx, dataoffset szCRLF
  1912. cCall ttywrite, dsbx
  1913. cEnd
  1914. endif
  1915. cProc SlowBoot,<PUBLIC,NEAR>
  1916. cBegin nogen
  1917. CheckKernelDS
  1918. ReSetKernelDS
  1919. GPPI macro sect, key, defval, file, storeit
  1920. push ds
  1921. push dataoffset sect
  1922. push ds
  1923. push dataoffset key
  1924. push defval
  1925. push ds
  1926. push dataoffset file
  1927. call GetPrivateProfileInt
  1928. ifb <storeit>
  1929. mov defval, ax
  1930. endif
  1931. endm
  1932. GPPS macro sect, key, defval, here, hereLen, file
  1933. push ds
  1934. push dataoffset sect
  1935. push ds
  1936. push dataoffset key
  1937. push ds
  1938. push dataoffset defval
  1939. push ds
  1940. push dataoffset here
  1941. push hereLen
  1942. push ds
  1943. push dataoffset file
  1944. call GetPrivateProfileString
  1945. endm
  1946. GPPS1 macro sect, key, defval, here, hereLen, file
  1947. push ds
  1948. push dataoffset sect
  1949. push ds
  1950. push key
  1951. push ds
  1952. push defval
  1953. push ds
  1954. push dataoffset here
  1955. push hereLen
  1956. push ds
  1957. push dataoffset file
  1958. call GetPrivateProfileString
  1959. endm
  1960. GPI macro sect, key, defval, storeit
  1961. push ds
  1962. push dataoffset sect
  1963. push ds
  1964. push dataoffset key
  1965. push defval
  1966. call GetProfileInt
  1967. ifb <storeit>
  1968. mov defval, ax
  1969. endif
  1970. endm
  1971. ife PMODE32
  1972. xor ax,ax
  1973. mov al,fPadCode
  1974. GPPI Standard, PadCodeStr, ax, BootFile, nostore
  1975. or al,ah
  1976. mov fPadCode,al
  1977. endif
  1978. if SHERLOCK
  1979. GPI szKernel, szGPC, gpEnable
  1980. endif
  1981. if KDEBUG
  1982. ifdef DISABLE
  1983. GPPI szDebugSect, szKRInfo, _krInfoLevel, BootFile
  1984. GPPI szDebugSect, szKRBreak, _krBreakLevel, BootFile
  1985. GPPI szDebugSect, szWin3Info, _Win3InfoLevel, Bootfile
  1986. GPPI szDebugSect, szWin3Break, _Win3BreakLevel, Bootfile
  1987. endif
  1988. endif ;KDEBUG
  1989. GPPS szDebugSect, szOutputTo, szAux, BootBuf, BootBufLen, BootFile
  1990. or ax, ax
  1991. jz @F
  1992. cmp ax, BootBufLen-2
  1993. jz @F
  1994. mov ah, 3ch ; creat file (zero length)
  1995. xor cx, cx
  1996. mov dx, dataOffset BootBuf
  1997. DOSCALL
  1998. jc @F
  1999. mov bx, ax
  2000. mov ah, 3eh ; now close it
  2001. DOSCALL
  2002. jc @F
  2003. mov ax, 3d42h ; open inherit, deny none, read/write
  2004. DOSCALL
  2005. jc @F
  2006. mov bx, ax ; dup handle
  2007. mov cx, 3 ; force AUX to be this file
  2008. mov ah, 46h
  2009. DOSCALL
  2010. mov ah, 3eh ; close temp file
  2011. DOSCALL
  2012. mov wDefRIP, 'i' ; since AUX is redirected, assume Ignore RIP
  2013. @@:
  2014. GPPI BootSect, FilesCached, MAXFHCACHELEN, BootFile, nostore
  2015. cmp ax, MINFHCACHELEN ; Validate length
  2016. jae @F
  2017. mov ax, MINFHCACHELEN
  2018. @@: cmp ax, MAXFHCACHELEN
  2019. jbe @F
  2020. mov ax, MAXFHCACHELEN
  2021. @@: mov fhCacheLen, ax ; Adjust # of cached file handles
  2022. shl ax, 1
  2023. shl ax, 1
  2024. add ax, dataoffset fhCache
  2025. mov fhCacheEnd, ax
  2026. GPPI BootSect, IdleSegLoad, 1, BootFile, nostore
  2027. mov fPokeAtSegments, al
  2028. ifdef WOW
  2029. GPPI BootSect, ExitLastApp, 0, BootFile, nostore
  2030. mov fExitOnLastApp, al
  2031. endif
  2032. mov bootExecBlock.lpfcb1.off,dataOffset win_show
  2033. mov bootExecBlock.lpfcb1.sel,ds
  2034. mov es,topPDB
  2035. mov bootExecBlock.lpcmdline.off,80h
  2036. mov bootExecBlock.lpcmdline.sel,es
  2037. mov lpBootApp.off,dataOffset app_name
  2038. mov lpBootApp.sel,ds
  2039. cmp graphics,1
  2040. jnz sb1
  2041. mov lpBootApp.off,dataOffset defapp
  2042. mov lpBootApp.sel,ds
  2043. sb1: mov di,dataOffset bootMods
  2044. sbloop1:
  2045. cCall LoadNewExe,<di>
  2046. SetKernelDS es
  2047. mov cx,-1
  2048. xor ax,ax
  2049. cld
  2050. repnz scasb
  2051. cmp di,dataOffset winmods
  2052. jb sbloop1
  2053. cmp graphics,1
  2054. jz sbloop2
  2055. ; cCall InitFwdRef
  2056. jmps sb4
  2057. UnSetKernelDS es
  2058. sbloop2: ; load USER.EXE, GDI.EXE
  2059. ifdef FE_SB
  2060. ;** If we just load the fae east modules, we want to
  2061. ;** checks the system locale vale which is far east
  2062. ;** locale.
  2063. ;** If system locale is not far east, then we skip
  2064. ;** to load far east module.
  2065. cmp di,dataOffset szBeforeWifeMan
  2066. je SB_DoFarEastModule
  2067. cmp di,dataOffset szBeforeWinNls
  2068. jne SB_DoLoadModule
  2069. SB_DoFarEastModule:
  2070. cCall GetSystemDefaultLangID
  2071. ; return: ax is system locale value
  2072. cmp ax,411h
  2073. je SB_DoLoadModule
  2074. cmp ax,412h
  2075. je SB_DoLoadModule
  2076. cmp ax,404h
  2077. je SB_DoLoadModule
  2078. cmp ax,804h
  2079. je SB_DoLoadModule
  2080. cmp ax,0c04h
  2081. je SB_DoLoadModule
  2082. ; skip to next module
  2083. mov cx,-1
  2084. xor ax,ax
  2085. cld
  2086. repnz scasb
  2087. jmp SB_NotKeyboardDriver
  2088. SB_DoLoadModule:
  2089. endif
  2090. cCall LoadNewExe,<di>
  2091. push ax ; Save hInst return value
  2092. SetKernelDS es
  2093. mov cx,-1
  2094. xor ax,ax
  2095. cld
  2096. repnz scasb
  2097. pop si ; Get hInst of latest module in SI
  2098. ;** If we just loaded the keyboard driver, we want to
  2099. ;** point our explicit link variables to the AnsiToOem and
  2100. ;** OemToAnsi functions so OpenFile can use them for the
  2101. ;** remaining boot modules
  2102. cmp di,dataOffset szAfterKeyboardDriver
  2103. jne SB_NotKeyboardDriver
  2104. push ds ; Save regs we care about
  2105. push di
  2106. regptr pStr,ds,bx
  2107. mov bx,dataOffset keyprocstr
  2108. cCall GetProcAddress,<si,pStr>
  2109. mov pKeyProc.off,ax
  2110. mov pKeyProc.sel,dx
  2111. mov bx,dataOffset keyprocstr1
  2112. cCall GetProcAddress,<si,pStr>
  2113. mov pKeyProc1.off,ax
  2114. mov pKeyProc1.sel,dx
  2115. pop di
  2116. pop ds
  2117. SB_NotKeyboardDriver:
  2118. cmp di,dataOffset defapp
  2119. jb sbloop2
  2120. ; OPTIMIZE BEGIN
  2121. ; OPTIMIZE END
  2122. sb4:
  2123. cCall InitFwdRef ; Gets stuff we can't dynalink to
  2124. cCall InternalEnableDOS ; Enable int21 hooks
  2125. ;sb4:
  2126. call check_TEMP
  2127. ; Get the shell name from SYSTEM.INI
  2128. mov ax,dataoffset Shell
  2129. GPPS1 BootSect, ax, lpBootApp.off, BootBuf, BootBufLen, BootFile
  2130. ;** Here we need to convert the command line to ANSI
  2131. cmp WORD PTR pKeyProc1[2],0 ; Paranoia...
  2132. jz @F
  2133. ;** Zero terminate the string before passing to OemToAnsi
  2134. mov es,bootExecBlock.lpcmdline.sel
  2135. mov bl,es:[80h] ; Get length byte
  2136. xor bh,bh
  2137. xchg BYTE PTR es:[bx+81h],bh ; Replace terminator char with zero
  2138. ;** Call the keyboard driver
  2139. push es ; Save the seg reg
  2140. push bx ; Save offset and char saved
  2141. push es
  2142. push 81h ; Always starts here (fixed offset)
  2143. push es
  2144. push 81h
  2145. cCall [pKeyProc1] ; Call OemToAnsi in keyboard driver
  2146. pop bx ; Get saved info
  2147. pop es
  2148. mov al,bh ; Saved char from string
  2149. xor bh,bh
  2150. mov BYTE PTR es:[bx+81h],al ; Replace the character
  2151. @@:
  2152. mov ax,dataOffset bootExecBlock
  2153. regptr dsax,ds,ax
  2154. cmp graphics,1
  2155. jz @F
  2156. cCall LoadModule,<lpBootApp,dsax>
  2157. jmps asdf
  2158. @@: cCall FlushCachedFileHandle,<hUser> ; in case 100 fonts are loaded
  2159. farptr lpBootBuf,ds,di
  2160. mov di, dataoffset BootBuf
  2161. cCall LoadModule,<lpBootBuf,dsax>
  2162. asdf:
  2163. cmp ax,32
  2164. jbe sb6
  2165. cCall GetExePtr,<ax>
  2166. mov hShell, ax
  2167. jmp bootdone
  2168. sb6:
  2169. ReSetKernelDS
  2170. les bx, lpBootApp
  2171. krDebugOut DEB_ERROR, "BOOT: unable to load @ES:BX"
  2172. cCall LoadFail,<lpBootApp>
  2173. ; cmp pDisableProc.sel,0 ; Is there a USER around yet?
  2174. ; jz @F
  2175. ; cCall pDisableProc
  2176. ;@@:
  2177. jmp bootfail
  2178. UnSetKernelDS
  2179. cEnd nogen
  2180. ;------------------------------------------------------------------------
  2181. assumes ds,nothing
  2182. assumes es,nothing
  2183. cProc LoadNewExe,<PUBLIC,NEAR>,<si,di>
  2184. parmW pname
  2185. cBegin
  2186. farptr lpparm,ax,ax
  2187. farptr lpBootBuf,ds,di
  2188. mov di, dataoffset BootBuf
  2189. CheckKernelDS
  2190. ReSetKernelDS
  2191. ifdef WOW
  2192. ; ATM Alters system.ini registry boot section to load its own SYSTEM.DRV
  2193. ; However on WOW this causes us to fail to load correctly. Also we
  2194. ; would be hard pushed to support the current 16 bit ATM since it relies
  2195. ; on internals of 16 bit GDI which are not present in WOW.
  2196. ; For this Beta I'm going to ignore the bootsection of the registry
  2197. ; when loading drivers and thus ATM will not get installed.
  2198. ; At least the user will be protected from not being able to boot WOW
  2199. ; BUGBUG - Consider
  2200. ; MattFe Oct9 92
  2201. mov di,pname
  2202. else
  2203. GPPS1 BootSect, pname, pname, BootBuf, BootBufLen, BootFile
  2204. endif
  2205. xor ax,ax
  2206. cCall LoadModule,<lpBootBuf,lpparm>
  2207. cmp ax,2
  2208. jne lne1
  2209. krDebugOut DEB_ERROR, "Can't find @DS:DI"
  2210. ; kerror ERR_LDBOOT,<BOOT: Unable to find file - >,ds,di
  2211. jmps lne4
  2212. lne1:
  2213. cmp ax,11
  2214. jne lne2
  2215. krDebugOut DEB_ERROR, "Invalid EXE file @DS:DI"
  2216. ; kerror ERR_LDBOOT,<BOOT: Invalid .EXE file - >,ds,di
  2217. jmps lne4
  2218. lne2:
  2219. cmp ax,15
  2220. jnz lne3
  2221. krDebugOut DEB_ERROR, "Invalid protect mode EXE file @DS:DI"
  2222. ; kerror ERR_LDBOOT,<BOOT: Invalid protect mode .EXE file - >,ds,di
  2223. jmps lne4
  2224. lne3:
  2225. cmp ax, 4
  2226. jne lne3a
  2227. krDebugOut DEB_ERROR, "Out of files (set FILES=30 in CONFIG.SYS) @DS:DI"
  2228. ; kerror ERR_LDFILES,<BOOT: Out of files, (set FILES=30 in CONFIG.SYS) loading - >,ds,di
  2229. jmps lne4
  2230. lne3a:
  2231. cmp ax, 32
  2232. jae lnex
  2233. NoLoadIt:
  2234. ; kerror ERR_LDBOOT,<BOOT: Unable to load - >,ds,pname
  2235. krDebugOut DEB_ERROR, "Unable to load @DS:DI (#ax)"
  2236. lne4:
  2237. cCall LoadFail,dsdi
  2238. mov ax,1
  2239. cCall ExitKernel,<ax>
  2240. lnex:
  2241. UnSetKernelDS
  2242. cEnd
  2243. sEnd INITCODE
  2244. ;-----------------------------------------------------------------------;
  2245. ; BootDone ;
  2246. ; ;
  2247. ; Boot is done when all of modules are loaded. Here we do a bit of ;
  2248. ; clean up, such as validating code segments, initing free memory to ;
  2249. ; CCCC, freeing up the fake TDB, and finally reallocating the init ;
  2250. ; code away. ;
  2251. ; ;
  2252. ; Arguments: ;
  2253. ; none ;
  2254. ; ;
  2255. ; Returns: ;
  2256. ; nothing ;
  2257. ; ;
  2258. ; Error Returns: ;
  2259. ; ;
  2260. ; Registers Preserved: ;
  2261. ; ;
  2262. ; Registers Destroyed: ;
  2263. ; all ;
  2264. ; ;
  2265. ; Calls: ;
  2266. ; ;
  2267. ; History: ;
  2268. ; ;
  2269. ; Wed Apr 15, 1987 08:53:23p -by- David N. Weise [davidw] ;
  2270. ; Added this nifty comment block. ;
  2271. ;-----------------------------------------------------------------------;
  2272. DataBegin INIT
  2273. externB beg_initdata
  2274. szKernel DB 'KERNEL',0
  2275. szWindows DB 'WINDOWS',0
  2276. if KDEBUG
  2277. szDebugOptions DB 'DebugOptions',0
  2278. szDebugFilter DB 'DebugFilter',0
  2279. szChecksum DB 'EnableSegmentChecksum',0
  2280. szSweepFreak DB 'LRUSweepFrequency',0
  2281. sz80x87 DB 'NoUse80x87',0
  2282. szFastFP DB 'FastFP', 0
  2283. externW DebugOptions
  2284. externW DebugFilter
  2285. ifdef DISABLE
  2286. externB fLoadTrace
  2287. endif
  2288. endif ; KDEBUG
  2289. ifdef SDEBUG
  2290. szEMSDebug DB 'EnableEMSDebug',0
  2291. endif
  2292. szgrab_386 DB '386GRABBER',0
  2293. if SWAPPRO
  2294. szSwapPro DB 'SwapProfile',0
  2295. szSwapFile DB 'SWAPPRO.DAT',0
  2296. endif
  2297. DataEnd INIT
  2298. sBegin INITCODE
  2299. assumes cs,CODE
  2300. assumes ds,nothing
  2301. assumes es,nothing
  2302. externB beg_initcode
  2303. cProc BootDone,<PUBLIC,NEAR>
  2304. cBegin nogen
  2305. SetKernelDS
  2306. if KDEBUG
  2307. ; Get win.ini [Windows] DebugOptions
  2308. GPI szWindows, szDebugOptions, DebugOptions
  2309. ; Get win.ini [Windows] DebugFilter
  2310. GPI szWindows, szDebugFilter, DebugFilter
  2311. ; Now set various internal flags based on DebugOptions
  2312. xor ax,ax
  2313. test DebugOptions,DBO_CHECKHEAP
  2314. jz @F
  2315. inc ax
  2316. @@:
  2317. mov es,pGlobalHeap
  2318. mov es:[hi_check],ax
  2319. test DebugOptions,DBO_CHECKFREE
  2320. jz @F
  2321. or Kernel_flags,kf_check_free
  2322. @@:
  2323. ifdef DISABLE
  2324. xor ax,ax
  2325. test DebugOptions,DBO_LOADTRACE
  2326. jz @F
  2327. mov fLoadTrace, al
  2328. @@:
  2329. endif ; DISABLE
  2330. test DebugOptions,DBO_DISABLEGPTRAPPING
  2331. jz wants_trapping
  2332. mov ax,0203h ; Reset GP fault.
  2333. mov bl,0Dh
  2334. mov cx,prevInt0Dproc.sel
  2335. mov dx,prevInt0Dproc.off
  2336. int 31h
  2337. mov ax,0203h ; Reset invalid op-code exception.
  2338. mov bl,06h
  2339. mov cx,prevIntx6proc.sel
  2340. mov dx,prevIntx6proc.off
  2341. int 31h
  2342. mov ax,0203h ; Reset page fault.
  2343. mov bl,0Eh
  2344. mov cx,prevInt0Eproc.sel
  2345. mov dx,prevInt0Eproc.off
  2346. int 31h
  2347. wants_trapping:
  2348. if SWAPPRO
  2349. GPI szKernel, szSwapPro, 1, nostore
  2350. mov fSwapPro, al
  2351. mov bx,TopPDB
  2352. mov ah,50h
  2353. pushf
  2354. FCLI
  2355. call prevInt21Proc
  2356. lea dx,szSwapFile
  2357. xor cx,cx
  2358. mov ah,3Ch
  2359. pushf
  2360. FCLI
  2361. call prevInt21Proc
  2362. mov hSwapPro,ax
  2363. mov bx,cur_dos_pdb
  2364. mov ah,50h
  2365. pushf
  2366. FCLI
  2367. call prevInt21Proc
  2368. endif
  2369. GPI szKernel, szChecksum, 1, nostore
  2370. mov fChkSum,al
  2371. GPI szKernel, sz80x87, 0, nostore
  2372. or ax,ax
  2373. jz wants_8087
  2374. mov f8087,0
  2375. and WinFlags,NOT WF1_80x87 ;Turn off corresponding WinFlags bit
  2376. wants_8087:
  2377. GPI szKernel, szFastFP, 1, nostore
  2378. mov fastFP, al
  2379. GPI szKernel, szSweepFreak, 500, nostore
  2380. else
  2381. mov ax, 500
  2382. endif ; KDEBUG
  2383. ifdef WOW
  2384. xor ax,ax
  2385. endif
  2386. or ax,ax
  2387. jz nolrusweep
  2388. test WinFlags[1], WF1_PAGING
  2389. jnz short nolrusweep
  2390. mov bx,codeOffset lrusweep
  2391. regptr csbx,cs,bx
  2392. xor dx,dx
  2393. cCall pTimerProc,<dx,ax,csbx>
  2394. nolrusweep:
  2395. if SDEBUG
  2396. GPI szKernel, szEMSDebug, 0, nostore
  2397. or ax,ax
  2398. jz no_EMS_debug_wanted
  2399. or Kernel_flags,kf_EMS_debug
  2400. no_EMS_debug_wanted:
  2401. endif
  2402. if LDCHKSUM
  2403. cCall ValidateCodeSegments
  2404. endif
  2405. if KDEBUG
  2406. mov fCheckFree,0
  2407. ife PMODE32
  2408. call init_free_to_CCCC
  2409. endif
  2410. endif
  2411. ; Get the shell name from SYSTEM.INI
  2412. GPPS BootSect, szgrab_386, szgrab_386, grab_name, 128, BootFile
  2413. mov es,curTDB ; ES = TDB of fake task
  2414. push es
  2415. cCall DeleteTask,<es> ; Flush bogus task
  2416. pop es
  2417. xor dx,dx
  2418. mov es:[TDB_sig],dx ; Clear signature word.
  2419. mov curTDB,dx ; Let someone else be current task
  2420. ; switch to the temp stack since we're about to Realloc the present one away
  2421. mov ax, ss
  2422. FCLI
  2423. SetKernelDS ss
  2424. mov sp,dataOffset gmove_stack
  2425. FSTI
  2426. cCall free_sel,<ax>
  2427. ; Shrink DGROUP down to its post initialization size
  2428. mov cx,dataOFFSET beg_initdata ; don't need init data
  2429. ; dx doubles as high word and specifies fixed
  2430. ; reallocation
  2431. xor dx,dx
  2432. cCall IGlobalReAlloc,<ds,dx,cx,dx> ; Realloc DGROUP
  2433. xor dx,dx
  2434. ; Now shrink the resident CODE segment
  2435. ife ROM
  2436. mov cx,codeOFFSET beg_initcode ; dont need init code
  2437. ; cCall IGlobalReAlloc,<cs,dxcx,dx>
  2438. ; jmps BootSchedule ; Jump to schedule first app
  2439. push cs ; Arguments to GlobalReAlloc
  2440. push dx
  2441. push cx
  2442. push dx
  2443. push cs ; Where GlobalReAlloc will eventually return
  2444. mov ax,codeOFFSET BootSchedule
  2445. push ax
  2446. jmp near ptr IGlobalReAlloc ; Jump to GlobalReAlloc
  2447. else ;ROM
  2448. jmp BootSchedule
  2449. endif
  2450. UnSetKernelDS ss
  2451. UnSetKernelDS
  2452. cEnd nogen
  2453. ;-----------------------------------------------------------------------;
  2454. ; check_TEMP
  2455. ;
  2456. ; If the environment variable TEMP points to garbage then GetTempFile
  2457. ; screws up. We fix it by wiping out the TEMP string if it points
  2458. ; to garbage.
  2459. ;
  2460. ; Entry:
  2461. ; none
  2462. ;
  2463. ; Returns:
  2464. ;
  2465. ; Registers Preserved:
  2466. ; all
  2467. ;
  2468. ; History:
  2469. ; Thu 11-May-1989 16:39:34 -by- David N. Weise [davidw]
  2470. ; Wrote it.
  2471. ;-----------------------------------------------------------------------;
  2472. assumes ds,nothing
  2473. assumes es,nothing
  2474. cProc check_TEMP,<PUBLIC,NEAR>,<ds,es>
  2475. ifdef FE_SB
  2476. localW pMyBuf
  2477. endif
  2478. cBegin
  2479. pusha
  2480. SetKernelDS
  2481. sub sp,130
  2482. mov di,sp
  2483. CheckKernelDS
  2484. mov ds,TopPDB
  2485. UnSetKernelDS
  2486. mov ds,ds:[PDB_environ]
  2487. xor si, si ; assume DS:SI points to environment
  2488. cCall GetTempDrive,<si>
  2489. smov es,ss
  2490. cld
  2491. stosw
  2492. ifdef FE_SB
  2493. mov pMyBuf,di ; save string offset(exclude D:)
  2494. endif
  2495. stmp2:
  2496. lodsw
  2497. or al,al ; no more enviroment
  2498. ifdef FE_SB
  2499. jnz @F ; I hate this
  2500. jmp stmpNo1
  2501. @@:
  2502. else
  2503. jz stmpNo1
  2504. endif
  2505. cmp ax,'ET' ; Look for TEMP=
  2506. jne stmp3
  2507. lodsw
  2508. cmp ax,'PM'
  2509. jne stmp3
  2510. lodsb
  2511. cmp al,'='
  2512. je stmpYes
  2513. stmp3: lodsb
  2514. or al,al
  2515. jnz stmp3
  2516. jmp stmp2
  2517. stmpYes:
  2518. push si ; save pointer to TEMP
  2519. push ds
  2520. push si ; spaces are legal, but they
  2521. lookForSpace: ; confuse too many apps, so
  2522. lodsb ; we treat them as illegal
  2523. cmp al, ' '
  2524. jz stmpFoundSpace
  2525. or al, al
  2526. jnz lookForSpace
  2527. pop si
  2528. cmp byte ptr [si+1],':'
  2529. jne stmpnodrive
  2530. and byte ptr [si],NOT 20h ; springboard needs this!
  2531. dec di
  2532. dec di
  2533. stmpnodrive:
  2534. lodsb
  2535. or al,al
  2536. jz stmpNo
  2537. stosb
  2538. jmp stmpnodrive
  2539. stmpNo:
  2540. mov ax,'~\'
  2541. cmp es:[di-1],al ; does it already end in \
  2542. jnz stmpNoF ; no, just store it
  2543. dec di ; override it
  2544. ifdef FE_SB
  2545. push si
  2546. mov si,pMyBuf
  2547. call FarMyIsDBCSTrailByte ;is that '\' a DBCS trailing byte?
  2548. cmc
  2549. adc di,0 ;skip it if yes.
  2550. pop si
  2551. endif
  2552. stmpNoF:
  2553. stosw
  2554. xor ax,ax
  2555. stosb ; zero terminate it
  2556. pop es ; recover pointer to TEMP
  2557. pop di
  2558. smov ds,ss
  2559. mov dx,sp
  2560. mov ax,5B00h
  2561. xor cx,cx
  2562. DOSCALL
  2563. jnc stmpClose
  2564. cmp al,80 ; Did we fail because the file
  2565. jz stmpNo1 ; already exists?
  2566. stmpNukeIt:
  2567. sub di,5 ; Get the TEMP= part.
  2568. @@: mov al,'x'
  2569. xchg al,es:[di]
  2570. inc di
  2571. or al,al
  2572. jnz @B
  2573. mov byte ptr es:[di-1],0
  2574. jmps stmpNo1
  2575. stmpClose:
  2576. mov bx,ax
  2577. mov ah,3Eh
  2578. DOSCALL
  2579. mov ah,41h
  2580. DOSCALL
  2581. stmpNo1:
  2582. add sp,130
  2583. popa
  2584. cEnd
  2585. stmpFoundSpace:
  2586. pop si
  2587. pop es
  2588. pop di
  2589. jmps stmpNukeIt
  2590. ;-----------------------------------------------------------------------;
  2591. ; get_windir
  2592. ;
  2593. ; Get a pointer to the 'windows' directory.
  2594. ;
  2595. ; Entry:
  2596. ; DS => environment string
  2597. ;
  2598. ; Returns:
  2599. ; CX = length of string
  2600. ; DI => WFP of 'windows' directory
  2601. ;
  2602. ; Registers Preserved:
  2603. ; all
  2604. ;
  2605. ; History:
  2606. ; Mon 16-Oct-1989 23:17:23 -by- David N. Weise [davidw]
  2607. ; Wrote it!
  2608. ;-----------------------------------------------------------------------;
  2609. assumes ds,nothing
  2610. assumes es,nothing
  2611. ifdef WOW
  2612. ;-----------------------------------------------------------------------;
  2613. ; original get_windir looks for the environment variable 'windir' (all
  2614. ; lowercase) to set the 'windows' directory.
  2615. ;
  2616. ; On NT the equivalent environment variable is 'SystemRoot' (all
  2617. ; uppercase). Hence the code is different.
  2618. ;
  2619. ; - nanduri
  2620. ;
  2621. ; There are some customers that used the undocumented trick on win31
  2622. ; of moving windir to some network location by putting win.com there.
  2623. ; The result would be that the "Windows Directory" would point
  2624. ; to the network location, and the system directory would be local.
  2625. ; Currently, the way WINDIR is supported involves hacks in a couple
  2626. ; of different places. What would be best is if you could do a
  2627. ; "set windir=xxxx" in your autoexec.nt and we would look for windir
  2628. ; here and we would code it to emulate win31 behavior. However, that's
  2629. ; broken right now, and windir is only regenerated after krnlx86.exe
  2630. ; has finished booting. So the approach taken here is to look for
  2631. ; a new environment variable called win16dir, and if it exists, make
  2632. ; the windows directory point to it. Systemroot is still used to
  2633. ; generate the system directory.
  2634. ;
  2635. ; We want to allow NT to be installed into a directory with a long
  2636. ; name, so we use GetShortPathName on the directory we get from
  2637. ; either SystemRoot or Win16Dir variables.
  2638. ; -- DaveHart 9-Feb-96
  2639. ;-----------------------------------------------------------------------;
  2640. szSystemRoot DB 'SYSTEMROOT=',0
  2641. szWin16Dir DB 'WIN16DIR=',0
  2642. cProc get_windir,<PUBLIC,NEAR>
  2643. cBegin nogen
  2644. push es
  2645. mov ax, cs ; the string is in 'cs', see above
  2646. mov es, ax
  2647. mov di, codeoffset szSystemRoot
  2648. call get_env_var_ptr
  2649. push dx
  2650. mov dx, ds
  2651. mov es, dx
  2652. SetKernelDS
  2653. mov si, dataoffset achRealWindowsDir
  2654. regptr esdi,es,di
  2655. regptr dssi,ds,si
  2656. mov cx, WINDIR_BUFSIZE
  2657. push dx
  2658. cCall GetShortPathName, <esdi, dssi, cx>
  2659. pop dx
  2660. mov cbRealWindowsDir,ax
  2661. mov ds, dx ;restore ds
  2662. pop dx
  2663. assumes ds,nothing
  2664. push cx
  2665. push di
  2666. mov ax, cs ; the string is in 'cs', see above
  2667. mov es, ax
  2668. mov di, codeoffset szWin16Dir
  2669. call get_env_var_ptr
  2670. or di, di ;does win16dir exist?
  2671. jz gw_not
  2672. add sp, 4 ;throw away systemroot
  2673. jmp short gw_cont
  2674. gw_not:
  2675. pop di
  2676. pop cx
  2677. gw_cont:
  2678. ; Now ds:di points to the Windows directory string in
  2679. ; the environment block. It may be a long pathname,
  2680. ; so fix it up.
  2681. smov es, ds
  2682. SetKernelDS
  2683. mov si, dataoffset achWindowsDir
  2684. regptr esdi,es,di
  2685. regptr dssi,ds,si
  2686. mov cx, WINDIR_BUFSIZE
  2687. cCall GetShortPathName, <esdi, dssi, cx>
  2688. mov cx, ax
  2689. smov ds, es
  2690. assumes ds,nothing
  2691. pop es
  2692. ret
  2693. cEnd nogen
  2694. cProc get_env_var_ptr,<PUBLIC,NEAR>
  2695. cBegin nogen
  2696. cld
  2697. push si
  2698. xor si,si
  2699. push di
  2700. mov cx,-1
  2701. xor ax,ax
  2702. repnz scasb
  2703. not cx
  2704. dec cx ; length of szSystemRoot
  2705. pop di
  2706. gw_cmp:
  2707. mov al, [si]
  2708. or al, al
  2709. jz gw_exit
  2710. push di
  2711. push cx
  2712. repz cmpsb ; compare the inputstring with szSystemRoot
  2713. pop cx
  2714. pop di
  2715. jnz gw_next ; not szSystemRoot
  2716. xor cx,cx ; yes szSystemRoot, cx=0 indicates so
  2717. mov di,si
  2718. gw_next:
  2719. lodsb
  2720. or al,al
  2721. jnz gw_next ; skip to the terminating NULL.
  2722. or cx,cx ; cx==0 implies... found szSystemRoot
  2723. jnz gw_cmp ; compare with the next environment string
  2724. mov cx,si ; here if found szSystemRoot.
  2725. sub cx,di
  2726. mov ax,di
  2727. dec cx
  2728. gw_exit:
  2729. mov di,ax
  2730. pop si
  2731. ret
  2732. cEnd nogen
  2733. ;-----------------------------------------------------------------------;
  2734. ; original get_windir is within the 'else' 'endif' block
  2735. ;
  2736. ;-----------------------------------------------------------------------;
  2737. else
  2738. cProc get_windir,<PUBLIC,NEAR>
  2739. cBegin nogen
  2740. cld
  2741. push si
  2742. xor di,di
  2743. xor si,si
  2744. gw: lodsw
  2745. or al,al ; no more enviroment
  2746. jz gw_exit
  2747. if ROM
  2748. if1
  2749. %out Take this out!
  2750. endif
  2751. ;;;!!!only until loader builds proper environment block
  2752. or ax,2020h ; ignore case of ENV string
  2753. endif
  2754. cmp ax,'iw' ; Look for windir=
  2755. jne @F
  2756. lodsw
  2757. if ROM
  2758. ;;;!!!only until loader builds proper environment block
  2759. or ax,2020h ; ignore case of ENV string
  2760. endif
  2761. cmp ax,'dn'
  2762. jne @F
  2763. lodsw
  2764. if ROM
  2765. ;;;!!!only until loader builds proper environment block
  2766. or ax,2020h ; ignore case of ENV string
  2767. endif
  2768. cmp ax,'ri'
  2769. jne @F
  2770. lodsb
  2771. cmp al,'='
  2772. je gw_got_it
  2773. @@: lodsb
  2774. or al,al
  2775. jnz @B
  2776. jmp gw
  2777. gw_got_it:
  2778. mov di,si
  2779. @@: lodsb
  2780. or al,al
  2781. jnz @B
  2782. mov cx,si
  2783. sub cx,di
  2784. dec cx
  2785. gw_exit:
  2786. pop si
  2787. ret
  2788. cEnd nogen
  2789. endif
  2790. sEnd INITCODE
  2791. ;------------------------------------------------------------------------
  2792. sBegin STACK
  2793. ; Boot TDB
  2794. boottdb equ this byte
  2795. DB SIZE TDB dup (0)
  2796. if 0
  2797. ;0123456789012345
  2798. ; Boot EEMS context save area
  2799. NUMBER_OF_BANKS = 4 * (0FFFFh - (LOWEST_SWAP_AREA * 64) + 1)/400h
  2800. boottdb_EEMSsave equ this byte
  2801. DB NUMBER_OF_BANKS + 100h DUP (0)
  2802. endif
  2803. ; do a clumsy paragraph alignment
  2804. rept 16
  2805. if ($ - boottdb) and 0Fh
  2806. db 0
  2807. endif
  2808. endm
  2809. ; Dummy arena entry so boot SS looks like a valid object
  2810. DB 'M'
  2811. DW -1
  2812. DW (BOOTSTACKSIZE + 31)/16
  2813. DB 0
  2814. DW 5 DUP (0)
  2815. ; Another in case we have to tweek the low order bit of SS
  2816. DB 'M'
  2817. DW -1
  2818. DW (BOOTSTACKSIZE + 15)/16
  2819. DB 0
  2820. DW 5 DUP (0)
  2821. ; Boot stack
  2822. stackbottom equ this word
  2823. DB BOOTSTACKSIZE DUP (0)
  2824. stacktop equ this word
  2825. DW -1
  2826. sEnd STACK
  2827. end BootStrap