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.

1331 lines
32 KiB

  1. title DOSINIT - Initialize dos specific static data.
  2. .xlist
  3. include kernel.inc
  4. include pdb.inc
  5. .list
  6. externFP GetModuleHandle
  7. externFP GetProcAddress
  8. externFP Int21Handler
  9. externFP GlobalDOSAlloc
  10. externFP GetFreeSpace
  11. ifdef FE_SB
  12. externFP GetSystemDefaultLangID
  13. endif ;FE_SB
  14. ifdef WOW
  15. externNP ExitKernel
  16. endif
  17. DataBegin
  18. externB graphics
  19. externB Kernel_flags
  20. externB DOS_version
  21. externB DOS_revision
  22. externB KeyInfo
  23. externB fFarEast
  24. ifdef FE_SB
  25. externB fDBCSLeadTable
  26. externB DBCSVectorTable
  27. endif ;FE_SB
  28. externB fBreak
  29. externB fNovell
  30. externB CurDOSDrive
  31. externB DOSDrives
  32. externW cur_dos_PDB
  33. externW Win_PDB
  34. externW f8087
  35. externW FileEntrySize
  36. externW topPDB
  37. externW headPDB
  38. externW hExeHead
  39. externW MyCSDS
  40. externW hGDI
  41. externW hUser
  42. externD pTimerProc
  43. externD pSftLink
  44. externD pFileTable
  45. externD myInt2F
  46. externD pMBoxProc
  47. externD pSysProc
  48. externD pGetFreeSystemResources
  49. externD plstrcmp
  50. ifdef JAPAN
  51. externD pJpnSysProc
  52. endif
  53. externD pKeyProc
  54. externD pKeyProc1
  55. externD pSErrProc
  56. externD pDisableProc
  57. externD pExitProc
  58. externD pMouseTermProc
  59. externD pKeyboardTermProc
  60. externD pKeyboardSysReq
  61. externD pSystemTermProc
  62. externD pDisplayCritSec
  63. externD pUserInitDone
  64. externD pPostMessage
  65. externD pSignalProc
  66. externD pIsUserIdle
  67. externD pUserGetFocus
  68. externD pUserGetWinTask
  69. externD pUserIsWindow
  70. externD curDTA
  71. externD InDOS
  72. if ROM
  73. externD pYieldProc
  74. externD pStringFunc
  75. externD prevInt21Proc
  76. externD prevInt00proc
  77. externD prevInt24Proc
  78. externD prevInt2FProc
  79. externD prevInt02proc
  80. externD prevInt04proc
  81. externD prevInt06proc
  82. externD prevInt07proc
  83. externD prevInt3Eproc
  84. externD prevInt75proc
  85. endif
  86. ifdef JAPAN
  87. ; Need this variable in order to make Kernel to hardware independent
  88. externW WinFlags
  89. endif
  90. DataEnd
  91. DataBegin INIT
  92. ; Win.com does version check, so this does not need to be internationalized.
  93. externB szDosVer
  94. ;msg0 DB 'Incorrect DOS version: DOS 3.1 or greater required.',13,10,'$'
  95. handles dw 10 dup(0)
  96. find_string db 'CON '
  97. name_string db 'CON',0
  98. DataEnd INIT
  99. sBegin CODE
  100. assumes cs,CODE
  101. ife ROM
  102. externD pYieldProc
  103. externD pStringFunc
  104. externD prevInt21Proc
  105. externD prevInt00proc
  106. externD prevInt24Proc
  107. externD prevInt2FProc
  108. externD prevInt02proc
  109. externD prevInt04proc
  110. externD prevInt06proc
  111. externD prevInt07proc
  112. externD prevInt3Eproc
  113. externD prevInt75proc
  114. ifdef WOW
  115. externD prevInt31proc
  116. endif
  117. endif
  118. sEnd CODE
  119. externNP DebugSysReq
  120. externNP SetOwner
  121. ;----------------------------------------------------------------------------;
  122. ; define any constans used in the file. ;
  123. ;----------------------------------------------------------------------------;
  124. SFT_GROW_LIM_IN_64K equ 8 ;if memory < 8*64k, grow to 100 handles
  125. ;else grow upto 127 handles
  126. SFT_HIGH_LIM equ 127 ;grow upto 127 when enough memory
  127. SFT_LOW_LIM equ 100 ;grow upto 100 when low in memory
  128. ;----------------------------------------------------------------------------;
  129. ; define any macros used in the file. ;
  130. ;----------------------------------------------------------------------------;
  131. SaveVec MACRO vec
  132. mov ax,35&vec&h
  133. pushf
  134. call prevInt21proc
  135. if ROM
  136. mov prevInt&vec&proc.off,bx
  137. mov prevInt&vec&proc.sel,es
  138. else
  139. mov ax,codeOffset prevInt&vec&proc
  140. SetKernelCSDword ax,es,bx
  141. endif
  142. ENDM
  143. ;----------------------------------------------------------------------------;
  144. DataBegin INIT
  145. sysmodstr DB 'SYSTEM',0
  146. keymodstr DB 'KEYBOARD',0
  147. displaymodstr DB 'DISPLAY',0
  148. mousemodstr DB 'MOUSE',0
  149. gdimodstr DB 'GDI',0
  150. usermodstr DB 'USER',0
  151. inqprocstr label byte
  152. msgprocstr label byte ; MessageBox in USER
  153. sysprocstr DB '#1',0 ; sysprocstr = InquireSystem
  154. timerprocstr DB '#2',0 ; timerprocstr = CreateSystemTimer
  155. keydisstr label byte ; keydisstr = DisableKeyboard
  156. mousedisstr DB '#3',0 ; mouseprocstr = DisableMouse
  157. disprocstr DB '#4',0 ; DisableOEMLayer in USER
  158. extprocstr label byte ; ExitWindows in USER
  159. coprocessor DB '#7',0 ; Get80x87SaveSize in system
  160. kbdfocus DB '#23',0 ; GetFocus in USER
  161. wintask DB '#224',0 ; GetWindowTask in USER
  162. iswindow DB '#47',0 ; IsWindow in USER
  163. signalproc DB '#314',0 ; SignalProc in user
  164. isuseridle DB '#333',0 ; IsUserIdle in user
  165. getfreesysrsc DB '#284',0 ; GetFreeSystemResources in user
  166. userlstrcmp DB '#430',0 ; lstrcmp in user
  167. stringfunc DB '#470',0 ; StringFunc in User.
  168. sysdisstr DB '#5',0 ; sysdisstr = DisableSystemTimers
  169. pmprocstr DB '#110',0 ; pmprocstr = PostMessage
  170. keysysreq DB '#136',0 ; keysysreq = EnableKBSysReq
  171. syserrorstr DB '#320',0 ; syserrorstr = SysErrorBox in USER
  172. yldprocstr DB '#332',0 ; yldprocstr = UserYield in USER
  173. udnprocstr DB '#400',0 ; tell user that initialization done
  174. displaycrit DB '#500',0 ; win386 interaction craziness
  175. ifdef JAPAN
  176. jpnsysprocstr db 'JapanInquireSystem',0 ; Kernel.JapanInquireSystem entry
  177. endif
  178. DataEnd INIT
  179. sBegin INITCODE
  180. assumes CS,CODE
  181. ;-----------------------------------------------------------------------;
  182. ; InitFwdRef ;
  183. ; ;
  184. ; Initializes the far call pointers to SYSTEM, USER, KEYBOARD. ;
  185. ; ;
  186. ; Arguments: ;
  187. ; ;
  188. ; Returns: ;
  189. ; ;
  190. ; Error Returns: ;
  191. ; ;
  192. ; Registers Preserved: ;
  193. ; ;
  194. ; Registers Destroyed: ;
  195. ; ;
  196. ; Calls: ;
  197. ; ;
  198. ; History: ;
  199. ; ;
  200. ; Tue Jan 06, 1987 04:21:13p -by- David N. Weise [davidw] ;
  201. ; Added this nifty comment block. ;
  202. ;-----------------------------------------------------------------------;
  203. assumes ds,nothing
  204. assumes es,nothing
  205. cProc InitFwdRef,<PUBLIC,NEAR>,<si,di>
  206. cBegin
  207. SetKernelDS
  208. mov ax,352Fh
  209. pushf
  210. call prevInt21proc
  211. mov myInt2F.sel,es
  212. mov myInt2F.off,bx
  213. ; Save current Int 00h, 21h, 24h, and 2Fh.
  214. SaveVec 00
  215. ;;; SaveVec 21
  216. SaveVec 24
  217. ; Get address of procedures in USER and SYSTEM modules that we will need.
  218. regptr pStr,ds,bx
  219. mov bx,dataOffset sysmodstr
  220. cCall GetModuleHandle,<pStr>
  221. mov si,ax
  222. mov bx,dataOffset sysprocstr
  223. cCall GetProcAddress,<si,pStr>
  224. mov pSysProc.off,ax
  225. mov pSysProc.sel,dx
  226. ifdef JAPAN
  227. mov bx,dataOffset jpnsysprocstr
  228. cCall GetProcAddress,<si,pStr>
  229. mov pJpnSysProc.off,ax
  230. mov pJpnSysProc.sel,dx
  231. endif
  232. mov bx,codeOffset ifr4
  233. push cs ; push return address
  234. push bx
  235. mov bx,dataOffset coprocessor
  236. cCall GetProcAddress,<si,pStr>
  237. push dx
  238. push ax ; push address to call
  239. ret_far ; call 8087 info
  240. ifr4:
  241. mov f8087,ax
  242. ifdef JAPAN
  243. ;;; int 1 ; debugging purpose only
  244. ; Since Japanese OEMs have non-IBM clone machines, Windows
  245. ; cannot use standard Bios interrupt to get system informations.
  246. ; In BootStrap (see LDBOOT.ASM), it uses Int 11h to obtain MCP's
  247. ; availability. However, Windows cannot use Int 11h (becase of
  248. ; IBM-dependant), MSKK has removed Int 11h from BootStrap.
  249. ;
  250. ; At this point, AX register contains MCP's availability, i.e.
  251. ; if AX has value zero, no MCP is installd. if AX has value except
  252. ; zero, MCP is installed. The following codes will update WinFlags
  253. ; and its exported variables by using AX register.
  254. test ax,ax ; MCP is installed?
  255. jz @F ; jump if not
  256. mov ax,WF1_80x87 shl 8 ; set MCP present bit
  257. @@:
  258. or WinFlags,ax ; update internal variable
  259. xor ax,ax
  260. mov dx,178 ; #178 is __WinFlags location for public use
  261. cCall GetProcAddress,<hExeHead,ax,dx>
  262. mov ax,WinFlags
  263. mov es:[bx],ax
  264. endif
  265. mov bx,dataOffset timerprocstr
  266. cCall GetProcAddress,<si,pStr>
  267. mov pTimerProc.off,ax
  268. mov pTimerProc.sel,dx
  269. mov bx,dataOffset sysdisstr
  270. cCall GetProcAddress,<si,pStr>
  271. mov pSystemTermProc.off,ax
  272. mov pSystemTermProc.sel,dx
  273. cmp graphics,0 ; Graphics?
  274. jne grp
  275. jmp nographics
  276. grp:
  277. ifndef WOW
  278. mov bx,dataOffset displaymodstr ; display stuff
  279. cCall GetModuleHandle,<pStr>
  280. mov bx,dataOffset displaycrit
  281. cCall GetProcAddress,<ax,pStr>
  282. mov pDisplayCritSec.off,ax
  283. mov pDisplayCritSec.sel,dx
  284. mov bx,dataOffset mousemodstr ; mouse stuff
  285. cCall GetModuleHandle,<pStr>
  286. mov si,ax
  287. mov bx,dataOffset mousedisstr
  288. cCall GetProcAddress,<si,pStr>
  289. mov pMouseTermProc.off,ax
  290. mov pMouseTermProc.sel,dx
  291. endif
  292. mov bx,dataOffset gdimodstr
  293. cCall GetModuleHandle,<pStr>
  294. mov hGDI,ax
  295. mov bx,dataOffset usermodstr ; user stuff
  296. cCall GetModuleHandle,<pStr>
  297. mov hUser,ax
  298. mov si,ax
  299. mov bx,dataOffset msgprocstr
  300. cCall GetProcAddress,<si,pStr>
  301. mov pMBoxProc.off,ax
  302. mov pMBoxProc.sel,dx
  303. mov bx,dataOffset syserrorstr
  304. cCall GetProcAddress,<si,pStr>
  305. mov word ptr pSErrProc[0],ax
  306. mov word ptr pSErrProc[2],dx
  307. mov bx,dataOffset extprocstr
  308. cCall GetProcAddress,<si,pStr>
  309. mov word ptr pExitProc[0],ax
  310. mov word ptr pExitProc[2],dx
  311. mov bx,dataOffset disprocstr
  312. cCall GetProcAddress,<si,pStr>
  313. mov word ptr pDisableProc[0],ax
  314. mov word ptr pDisableProc[2],dx
  315. mov bx,dataOffset yldprocstr
  316. cCall GetProcAddress,<si,pStr>
  317. ife ROM
  318. mov bx, codeOFFSET pYieldProc
  319. SetKernelCSDword bx,dx,ax
  320. else
  321. mov pYieldProc.off,ax
  322. mov pYieldProc.sel,dx
  323. endif
  324. mov bx,dataOffset udnprocstr
  325. cCall GetProcAddress,<si,pStr>
  326. mov word ptr pUserInitDone[0],ax
  327. mov word ptr pUserInitDone[2],dx
  328. mov bx,dataOffset pmprocstr
  329. cCall GetProcAddress,<si,pStr>
  330. mov word ptr pPostMessage[0],ax
  331. mov word ptr pPostMessage[2],dx
  332. mov bx,dataOffset signalproc
  333. cCall GetProcAddress,<si,pStr>
  334. mov word ptr pSignalProc[0],ax
  335. mov word ptr pSignalProc[2],dx
  336. ; These are never called in WOW
  337. ifndef WOW
  338. mov bx,dataOffset isuseridle
  339. cCall GetProcAddress,<si,pStr>
  340. mov word ptr pIsUserIdle[0],ax
  341. mov word ptr pIsUserIdle[2],dx
  342. mov bx,dataOffset getfreesysrsc
  343. cCall GetProcAddress,<si,pStr>
  344. mov word ptr pGetFreeSystemResources[0],ax
  345. mov word ptr pGetFreeSystemResources[2],dx
  346. endif
  347. mov bx,dataOffset userlstrcmp
  348. cCall GetProcAddress,<si,pStr>
  349. mov word ptr plstrcmp[0],ax
  350. mov word ptr plstrcmp[2],dx
  351. mov bx,dataOffset stringfunc
  352. cCall GetProcAddress,<si,pStr>
  353. if ROM
  354. mov pStringFunc.off,ax
  355. mov pStringFunc.sel,dx
  356. else
  357. mov bx, codeOFFSET pStringFunc
  358. SetKernelCSDword bx,dx,ax
  359. endif
  360. mov bx,dataOffset kbdfocus
  361. cCall GetProcAddress,<si,pStr>
  362. mov word ptr pUserGetFocus[0],ax
  363. mov word ptr pUserGetFocus[2],dx
  364. mov bx,dataOffset wintask
  365. cCall GetProcAddress,<si,pStr>
  366. mov word ptr pUserGetWinTask[0],ax
  367. mov word ptr pUserGetWinTask[2],dx
  368. mov bx,dataOffset iswindow
  369. cCall GetProcAddress,<si,pStr>
  370. mov word ptr pUserIsWindow[0],ax
  371. mov word ptr pUserISWindow[2],dx
  372. mov bx,dataOffset keymodstr
  373. cCall GetModuleHandle,<pStr>
  374. mov si,ax
  375. mov bx,dataOffset keydisstr
  376. cCall GetProcAddress,<si,pStr>
  377. mov word ptr [pKeyboardTermProc],ax
  378. mov word ptr [pKeyboardTermProc+2],dx
  379. mov bx,dataOffset keysysreq
  380. cCall GetProcAddress,<si,pStr>
  381. mov pKeyboardSysReq.off,ax
  382. mov pKeyboardSysReq.sel,dx
  383. mov ax,4
  384. cCall pKeyboardSysReq,<ax> ; tell kbd to pass SysReq to CVWBreak
  385. mov bx,dataOffset KeyInfo
  386. push ds
  387. push bx ; push argument to keyboard.inquire
  388. mov bx,codeOffset ifr1
  389. push cs ; push return address
  390. push bx
  391. mov bx,dataOffset inqprocstr
  392. cCall GetProcAddress,<si,pStr>
  393. push dx
  394. push ax ; push address to call
  395. ret_far ; call keyboard inquire
  396. ifr1:
  397. ifndef JAPAN
  398. ; This is DBCS kernel. So do not get information from keyboard
  399. ; driver. This K/B spec is old one and should be ignored.
  400. ; We use DOS DBCS vector instead of K/B table.
  401. ; 071191 Yukini
  402. ;
  403. ;ifndef KOREA ;Korea might want to remove this too.
  404. ;!!!! Note to Taiwan developers !!!
  405. ; The following code fragment is necessary for those countries
  406. ; who want to run DBCS Windows on top of SBCS MS-DOS.
  407. ; For example, Taiwan might need this feature.
  408. ; Japan and Korea are safe to remove this fragment as Japanese
  409. ; and Hangeul Windows all assume DBCS MS-DOS.
  410. mov si,dataOffset KeyInfo+KbRanges
  411. lodsw
  412. cmp al,ah
  413. jbe ifr2
  414. lodsw
  415. cmp al,ah
  416. ja ifr3
  417. ifr2: inc fFarEast
  418. ifdef FE_SB
  419. ;
  420. ; setup DBCS lead byte flag table after keyboard driver is loaded
  421. ;
  422. mov di, dataOffset fDBCSLeadTable ; clear table before begin...
  423. mov cx, 128
  424. xor ax, ax
  425. push es
  426. push ds
  427. pop es
  428. cld
  429. rep stosw
  430. pop es
  431. mov si, dataOffset KeyInfo+KbRanges
  432. mov cx, 2
  433. idr1:
  434. lodsw ; fetch a DBCS lead byte range
  435. cmp al, ah ; end of range info?
  436. ja idr3 ; jump if so.
  437. call SetDBCSVector
  438. loop idr1 ; try another range
  439. idr3:
  440. endif ;FE_SB
  441. endif ;NOT JAPAN
  442. jmps ifr3
  443. ;
  444. ; Substitute dummy procs if user/gdi/keyboard/display not present
  445. ;
  446. if 0
  447. externFP <DummyKeyboardOEMToAnsi>
  448. endif
  449. externFP <OldYield>
  450. nographics:
  451. ife ROM
  452. push di
  453. push bx
  454. if 0
  455. mov bx, codeOffset pKeyProc
  456. mov di, codeOffset DummyKeyboardOEMToAnsi
  457. ; SetKernelCSDword bx,cs,di
  458. endif
  459. mov bx, codeOffset pYieldProc
  460. mov di, codeOffset OldYield
  461. SetKernelCSDword bx,cs,di
  462. pop bx
  463. pop di
  464. else
  465. mov pYieldProc.off,codeOffset OldYield
  466. mov pYieldProc.sel,cs
  467. endif
  468. ifr3:
  469. call DebugSysReq
  470. cEnd
  471. assumes ds,nothing
  472. assumes es,nothing
  473. ;-----------------------------------------------------------------------;
  474. ; InitDosVarP ;
  475. ; ;
  476. ; Records for future use various DOS variables. ;
  477. ; ;
  478. ; Arguments: ;
  479. ; ES = PDB of Kernel ;
  480. ; ;
  481. ; Returns: ;
  482. ; AX != 0 if successful ;
  483. ; ;
  484. ; Error Returns: ;
  485. ; ;
  486. ; Registers Preserved: ;
  487. ; DI,SI,DS,ES ;
  488. ; ;
  489. ; Registers Destroyed: ;
  490. ; BX,CX,DX ;
  491. ; ;
  492. ; Calls: ;
  493. ; ;
  494. ; History: ;
  495. ; ;
  496. ; Mon 07-Aug-1989 23:50:20 -by- David N. Weise [davidw] ;
  497. ; Removed more dicking around by removing WinOldApp support. ;
  498. ; ;
  499. ; Tue Feb 03, 1987 10:45:31p -by- David N. Weise [davidw] ;
  500. ; Removed most of the dicking around the inside of DOS for variable ;
  501. ; locations. Variables are now got and set the right way: through DOS ;
  502. ; calls. This should allow Windows to run in the DOS 5 compatibility ;
  503. ; box as well as under future versions of real mode DOS. ;
  504. ; ;
  505. ; Tue Jan 06, 1987 04:33:16p -by- David N. Weise [davidw] ;
  506. ; Added this nifty comment block. ;
  507. ;-----------------------------------------------------------------------;
  508. assumes ds,nothing
  509. assumes es,nothing
  510. cProc InitDosVarP,<PUBLIC,NEAR>,<bx,cx,dx,si,di,es>
  511. cBegin
  512. ReSetKernelDS
  513. ; Save our PDB pointer in the code segment
  514. mov ax,es
  515. mov topPDB,ax
  516. mov headPDB,ax
  517. mov es:[PDB_Chain],0 ; the buck stops here
  518. ; record current PDB
  519. mov cur_dos_PDB,ax
  520. mov Win_PDB,ax
  521. ; record current DTA
  522. mov curDTA.sel,ax
  523. mov curDTA.off,80h
  524. ; disable ^C checking as fast as possible
  525. mov ax,3300h ; remember ^C state
  526. int 21h
  527. mov fBreak,dl
  528. mov ax,3301h ; disable ^C checking
  529. mov dl,0
  530. int 21h
  531. ; record in_dos pointer
  532. mov ah,34h
  533. int 21h
  534. mov InDOS.sel,es
  535. mov InDOS.off,bx
  536. mov ah, 19h
  537. int 21h
  538. mov CurDOSDrive, al ; Initialize current drive tracking
  539. mov dl, al
  540. mov ah, 0Eh
  541. int 21h
  542. mov DOSDrives, al ; For returning from Select Disk calls
  543. ; To avoid beaucoup thought, let's init prevInt21Proc right now!
  544. ;
  545. ; This was done as a last minute hack to 2.10. I forget the
  546. ; motivation for it, other than it fixed a couple of bugs
  547. ; having to do with error recovery. It did introduce one
  548. ; bug with one error path having to do with Iris, but I don't
  549. ; remember that either. Interested parties can grep for
  550. ; prevInt21Proc and think hard and long.
  551. ;
  552. ; Since we now call through prevInt21Proc in many places rather
  553. ; than use int 21h (saves ring transitions), this had better stay here!
  554. ; See the DOSCALL macro.
  555. ;
  556. mov ax, 3521h
  557. int 21h
  558. if ROM
  559. mov prevInt21Proc.off,bx
  560. mov prevInt21Proc.sel,es
  561. else
  562. mov ax,codeOffset prevInt21Proc
  563. SetKernelCSDword ax,es,bx
  564. endif
  565. ifdef WOW
  566. ;
  567. ; We save the int 31 vector here to avoid emulation of int 31 instructions.
  568. ; THIS WILL BREAK INT 31 HOOKERS. Currently we don't beleive that any
  569. ; windows apps hook int 31.
  570. mov ax, 3531h
  571. int 21h
  572. mov ax,codeOffset prevInt31Proc
  573. SetKernelCSDword ax,es,bx
  574. endif
  575. ; moved here 8 feb 1990 from InitFwdRef, no good reason for
  576. ; leaving 0 behind, except that's the way we did it in 2.x.
  577. ; Save current Int 02h, 04h, 06h, 07h, 3Eh, and 75h.
  578. SaveVec 02
  579. SaveVec 04
  580. SaveVec 06
  581. SaveVec 07
  582. SaveVec 3E
  583. SaveVec 75
  584. ; get the 2F
  585. ; this slime is an old novell hack
  586. SaveVec 2F ; and can probably be removed!
  587. ; See if we are under NOVELL
  588. mov ah, 0DCh
  589. int 21h
  590. mov fNovell, al
  591. ; Get MSDOS version number
  592. mov ah,30h
  593. int 21h
  594. ifdef TAKEN_OUT_FOR_NT
  595. cmp al,10 ; is it the DOS 5 compatibility box?
  596. jae got_ver
  597. cmp al,4 ; > 4.xx?
  598. jae got_ver
  599. cmp al,3 ; < 3.0 ?
  600. jb dos_version_bad
  601. cmp ah,10
  602. jae got_ver ; < 3.1 ?
  603. dos_version_bad:
  604. jmps fail
  605. endif
  606. got_ver:
  607. mov DOS_version,al
  608. mov DOS_revision,ah
  609. ; Remember where the end of the SFT table is, so if we decide to
  610. ; add file handles we can remove them on exit
  611. ;
  612. ; DOS 3.10 =< version =< DOS 3.21 => FileEntrySize = 53
  613. ; DOS 3.21 < version < DOS 4.00 => unknown
  614. ; DOS 4.00 =< version =< DOS 4.10 => FileEntrySize = 58
  615. ; DOS 4.10 < version => unknown
  616. ; version = DOS 10 => FileEntrySize = 00
  617. ; OS|2
  618. xor bx,bx
  619. ifdef TAKEN_OUT_FOR_NT
  620. cmp al,10 ; OS|2 can't mess with SFTs
  621. jae have_file_size
  622. ; DOS 3
  623. cmp al,3
  624. ja DOS_4
  625. mov bx,56
  626. cmp ah,0
  627. jz have_file_size
  628. mov bx,53
  629. cmp ah,31
  630. jbe have_file_size
  631. jmps unknown_DOS
  632. DOS_4: ; REMOVED FOLLOWING! DOS 3.4 will be
  633. ; called 4.0 so we don't know the size!
  634. ;;; mov bx,58
  635. ;;; cmp ah,1 ; DOS 4
  636. ;;; jbe have_file_size
  637. unknown_DOS:
  638. push ax
  639. call GetFileSize
  640. mov bx,ax
  641. pop ax
  642. cmp bx,-1
  643. jz fail
  644. endif
  645. have_file_size:
  646. mov FileEntrySize,bx
  647. mov al,10 ; don't want to mess with SFT's!
  648. ifdef FE_SB
  649. ;During boot,
  650. ;Use thunked API GetSystemDefaultLangID() to set DBCS leadbyte table
  651. cCall GetSystemDefaultLangID
  652. xor bx,bx
  653. Search_LangID:
  654. mov dx,word ptr DBCSVectorTable[bx] ;get language ID
  655. test dx,dx ;if end of table,
  656. jz DBCS_Vector_X ;exit
  657. cmp ax,dx ;match LangID?
  658. jz LangID_Find ;yes
  659. add bl, DBCSVectorTable[bx+2] ;point to next DBCS vector
  660. add bl, 3 ;point to DBCS leadbyte range
  661. jmps Search_LangID ;continue search
  662. LangID_Find:
  663. mov cl, DBCSVectorTable[bx+2] ;get DBCS vector size
  664. Set_DBCS_Vector:
  665. sub cl, 2
  666. jc DBCS_Vector_X
  667. mov ax, word ptr DBCSVectorTable[bx+3] ;set DBCS vector
  668. push bx
  669. call SetDBCSVector
  670. pop bx
  671. add bl, 2
  672. jmps Set_DBCS_Vector
  673. DBCS_Vector_X:
  674. endif ;FE_SB
  675. mov ax,-1
  676. jmps initdone
  677. fail:
  678. mov dx,dataOffset szDosVer ;msg0
  679. mov ah,09
  680. int 21h
  681. xor ax,ax
  682. initdone:
  683. cEnd
  684. ifdef FE_SB
  685. ;-----------------------------------------------------------------------;
  686. ; SetDBCSVector ;
  687. ; ;
  688. ; Setup fDBCSLeadTable ;
  689. ; ;
  690. ; Arguments: ;
  691. ; AL = First DBCS lead byte ;
  692. ; AH = Final DBCS lead byte ;
  693. ; ;
  694. ; Returns: ;
  695. ; NONE ;
  696. ; ;
  697. ; Registers Destroyed: ;
  698. ; BX ;
  699. ; Calls: ;
  700. ; NONE ;
  701. ; ;
  702. ;-----------------------------------------------------------------------;
  703. cProc SetDBCSVector,<PUBLIC,NEAR>
  704. cBegin nogen
  705. mov bl, al ;
  706. xor bh, bh ;
  707. idr2:
  708. mov byte ptr fDBCSLeadTable[bx], 1 ; set "DBCS lead byte"
  709. inc bl
  710. cmp bl, ah ; end of range?
  711. jle idr2 ; jump if not
  712. mov fFarEast,1 ; I am in DBCS world. 071191 Yukini.
  713. ret
  714. cEnd nogen
  715. endif
  716. ;-----------------------------------------------------------------------;
  717. ; GetFileSize ;
  718. ; ;
  719. ; Measures the SFT entry size for DOS versions we don't know about. ;
  720. ; ;
  721. ; Arguments: ;
  722. ; none ;
  723. ; ;
  724. ; Returns: ;
  725. ; AX = SFT size ;
  726. ; ;
  727. ; Error Returns: ;
  728. ; AX = -1 ;
  729. ; ;
  730. ; Registers Preserved: ;
  731. ; ;
  732. ; Registers Destroyed: ;
  733. ; ;
  734. ; Calls: ;
  735. ; ;
  736. ; History: ;
  737. ; ;
  738. ; Mon Aug 03, 1987 02:42:15p -by- David N. Weise [davidw] ;
  739. ; Rickz wrote it. ;
  740. ; ;
  741. ; Modifications: ;
  742. ; -by- Amit Chatterjee. ;
  743. ; ;
  744. ; The original method of opening 5 files and looking for 3 consecutive ;
  745. ; ones would not succeed always. IRMALAN when run as a TSR from standar-;
  746. ; -d mode Windows would leave a file open (it probably opens 3 files ;
  747. ; when pooped into the host and leaves the third one open). Next time ;
  748. ; on starting windows, the index of the above 5 files that this routine ;
  749. ; would open would be 3,4,5,6 & 8 (SFT entry no). Of these the first ;
  750. ; 2 would be in one node so this woutine would not find 3 consecutive ;
  751. ; entries and Windows would not start up. ;
  752. ; ;
  753. ; To work around this, we try to open 5 at first. If we fail, then we ;
  754. ; leave the 5 open and open another 5. ;
  755. ; ;
  756. ; !!! At some point we should try to figure out why IRMALAN leaves a ;
  757. ; file open. ;
  758. ;-----------------------------------------------------------------------;
  759. assumes ds,nothing
  760. assumes es,nothing
  761. cProc GetFileSize,<PUBLIC,NEAR>
  762. cBegin nogen
  763. CheckKernelDS
  764. ReSetKernelDS
  765. mov si,dataOffset handles
  766. cCall GetFileSize1
  767. cmp ax,-1 ;did it succeed ?
  768. jnz @f ;yes.
  769. mov si,dataOffset handles+10;place for another five
  770. cCall GetFileSize1 ;try to get it
  771. @@:
  772. push ax ;save return value
  773. ; close files that were opened
  774. mov si,dataOffset handles
  775. mov cx,10
  776. close_file_loop: ; close the file for each handle
  777. mov ax,3E00h
  778. mov bx,[si]
  779. or bx,bx ; no more open ?
  780. jz close_file_done
  781. int 21h
  782. add si,2
  783. loop close_file_loop
  784. close_file_done:
  785. pop ax ;get back return value
  786. ret
  787. cEnd nogen
  788. cProc GetFileSize1,<PUBLIC,NEAR>
  789. cBegin nogen
  790. mov dx,dataOffset name_string
  791. mov cx,5
  792. open_file_loop: ; open the console four times
  793. mov ax,3D00H
  794. int 21h
  795. mov [si],ax ; save the handle
  796. add si,2
  797. loop open_file_loop
  798. xor di,di ; start searching from 0:0
  799. ; get a selector for searching from 0:0
  800. mov ax,0 ;get a free slector
  801. mov cx,1 ;only 1 selector to allocate
  802. int 31h ;ax has selector
  803. xor cx,cx ;hiword of initial base
  804. push dx
  805. xor dx,dx ;loword of initial base
  806. mov bx,ax ;get the selector
  807. call SetSelectorBaseLim64k ;base is at 0:0
  808. pop dx
  809. mov es,bx
  810. get_first:
  811. call find_con ; find first 'CON\0'
  812. cmp ax,-1
  813. jz no_table
  814. cmp ax,-2
  815. jnz get_second
  816. search_again:
  817. push bx
  818. mov bx,es ;get the slector
  819. ; add FFD paragraphs to the base to get to next segment
  820. mov ax,0FFDh ;paragraphs to offset base by
  821. push dx
  822. call AddParaToBase ;update base
  823. pop dx
  824. mov es,bx ;have the updated selector
  825. pop bx
  826. xor di,di
  827. jmp get_first
  828. get_second:
  829. mov bx,ax ; bx is location of first 'CON\0'
  830. and bx,000Fh
  831. shr ax,1
  832. shr ax,1
  833. shr ax,1
  834. shr ax,1
  835. push bx ;save
  836. mov bx,es ;get the base
  837. push dx
  838. call AddParaToBase ;add AX paras to base
  839. pop dx
  840. mov es,bx ;have the updated base
  841. pop bx ;restore
  842. mov di,bx
  843. add di, 3 ; kludge for the size of desired string
  844. call find_con ; find second 'CON\0'
  845. cmp ax,-1
  846. jz no_table
  847. cmp ax,-2
  848. jz search_again
  849. mov dx,ax ; dx is location of second 'CON\0'
  850. sub dx,bx
  851. cmp dx,100h ; file entries are within 100h bytes of another
  852. ja get_second
  853. mov bx,dx ; bx is distance between the first two
  854. mov dx,ax ; dx is location of second 'CON\0'
  855. get_third:
  856. call find_con
  857. cmp ax,-1
  858. jz no_table
  859. cmp ax,-2
  860. jz search_again
  861. mov cx,ax ; ax & cx = location of third 'CON\0'
  862. sub cx,dx ; cx is distance between the 2nd & 3rd
  863. sub bx,cx ; bx = the difference in distances
  864. jz found
  865. cmp cx,100h ; file entries are within 100h bytes of another
  866. ja get_second
  867. mov bx,cx ; bx is distance between the two
  868. mov dx,ax ; dx is location of the last 'CON\0'
  869. jmp get_third
  870. found:
  871. mov ax,cx ; store file table entry size in ax
  872. no_table:
  873. ; if the temp selector had been allocated free it.
  874. push bx
  875. push ax
  876. mov bx,es
  877. xor ax,ax
  878. mov es,ax
  879. or bx,bx ;allocated ?
  880. jz @f ;no.
  881. mov ax,1 ;free selector
  882. int 31h ;free it
  883. @@:
  884. pop ax
  885. pop bx ;restore
  886. ret
  887. find_con:
  888. mov ax,es
  889. push dx ;save
  890. push bx
  891. mov bx,ax ;get the slector
  892. call GetSelectorSegment ;DX returns segment value
  893. mov ax,dx ;get the segment value
  894. pop bx
  895. pop dx ;restore
  896. cmp ax,8000h
  897. ja not_found
  898. xor ax,ax
  899. mov al, byte ptr [find_string]
  900. try_again:
  901. mov cx,0FFF0h
  902. sub cx,di
  903. repnz scasb ; search for the first letter ('C')
  904. jz continue
  905. mov ax,-2
  906. jmps temp_ret
  907. ; ret
  908. continue:
  909. mov cx,3
  910. mov si, dataOffset find_string+1
  911. repz cmpsb ; search for the next three letters
  912. jnz find_con
  913. lea ax,[di-4] ; return the string's location in ax
  914. temp_ret:
  915. ret
  916. not_found:
  917. mov ax,-1
  918. ret
  919. cEnd nogen
  920. ;----------------------------------------------------------------------------;
  921. ; AddParaToBase: ;
  922. ; ;
  923. ; Given a selector in BX and a para value in AX, it updates the base of the ;
  924. ; selector by AX paras. In real mode, it just adds AX to BX. The modified ;
  925. ; selector/segment is returned in BX. ;
  926. ;----------------------------------------------------------------------------;
  927. AddParaToBase proc near
  928. push ax ;save
  929. mov ax,6 ;get base address code
  930. int 31h ;cx:dx has current base address
  931. pop ax ;get back the offset in para
  932. push bx ;use as work register
  933. xor bx,bx ;zero out
  934. shl ax,1 ;shift out a bit
  935. rcl bx,1 ;gather into bx
  936. shl ax,1 ;shift out a bit
  937. rcl bx,1 ;gather into bx
  938. shl ax,1 ;shift out a bit
  939. rcl bx,1 ;gather into bx
  940. shl ax,1 ;shift out a bit
  941. rcl bx,1 ;gather into bx
  942. add dx,ax ;add low word of offset
  943. adc cx,0 ;update hiword
  944. add cx,bx ;update hiword of offset
  945. pop bx ;get back selector
  946. mov ax,7 ;set selector base code
  947. int 31h ;the base of the selector has been set
  948. inc ax ;set selector limit code
  949. mov dx,-1 ;64-1k limit
  950. xor cx,cx ;cx:dx=64-1k
  951. int 31h ;limit set to 64-1k
  952. ret
  953. AddParaToBase endp
  954. ;----------------------------------------------------------------------------;
  955. ;----------------------------------------------------------------------------;
  956. ; GrowSFTToMax: ;
  957. ; ;
  958. ; This routine is invoked only in protected mode and grows the SFT to its max;
  959. ; size by linking in one more tanle entry. ;
  960. ;----------------------------------------------------------------------------;
  961. assumes ds,nothing
  962. assumes es,nothing
  963. cProc GrowSFTToMax,<NEAR,PUBLIC,PASCAL>,<es,ax,di>
  964. localW NewHandles ;# of extra handles being allocated
  965. localW NewTableSize ;size of newtable
  966. localB GrowLimit ;size to grow sft to
  967. cBegin
  968. ReSetKernelDS
  969. ; get the amount of free space and decide on the number of handle entries that
  970. ; we want to add. If the memory space is more than 8*64K, make the total number
  971. ; of handle entries 256 else make it 100.
  972. mov GrowLimit,SFT_HIGH_LIM ;assume we will grow upto 255
  973. xor bx,bx ;dummy parameter
  974. cCall GetFreeSpace,<bx> ;dx:ax returns free area size
  975. cmp dx,SFT_GROW_LIM_IN_64K ;is it more than or equal (in 64k incs)
  976. jae @f ;yes
  977. mov GrowLimit,SFT_LOW_LIM ;low on memory, grow till 100
  978. @@:
  979. ; allocate a free selector.
  980. xor ax,ax ;allocate selector function code
  981. mov cx,1 ;need to get 1 selector
  982. int 31h ;ax has the selector
  983. ; get the address of the first in the SFT chain.
  984. push ax ;save the slector
  985. mov ah,52h ;get SYSVARS call
  986. int 21h ;es:bx points to DOS SYSVAR structure
  987. lea bx,[bx+sftHead] ;es:bx points to the start of the sft
  988. mov cx,es:[bx][2] ;get the segment
  989. mov dx,es:[bx] ;get the offset
  990. pop ax ;get back the free selector
  991. ; modify the base of the free selector to point to the first link in the system
  992. ; file table list.
  993. mov bx,ax ;get the selector here
  994. call SetSelectorBaseLim64k ;set selector base and limit.
  995. ; now get into a loop, to find out the number of file handles that the system
  996. ; currently.
  997. xor ah,ah ;will count handles here.
  998. mov es,bx ;es points to the first entry
  999. CountNumHandles:
  1000. xor bx,bx ;es:bx points to first table
  1001. mov cx,es:[bx].sftCount ;get the number of handles
  1002. add ah,cl ;accumulate no of handles here
  1003. cmp word ptr es:[bx],-1 ;end of chain ?
  1004. jz AddOneMoreSFTLink ;end of current list reached
  1005. mov cx,word ptr es:[bx].sftLink[2];get the segment of next node
  1006. mov dx,word ptr es:[bx].sftLink[0];get the offset of the next node
  1007. mov bx,es ;get the selector
  1008. call SetSelectorBaseLim64k ;modify sel to point to next node
  1009. jmp short CountNumHandles ;continue
  1010. AddOneMoreSFTLink:
  1011. ; find out the number of extra handles for which we will allocate space
  1012. mov al,GrowLimit ;max number of handles
  1013. cmp ah,al ;is it already more than limit ?
  1014. jae GrowSFTToMaxRet ;no need to grow any more.
  1015. ifdef WOW
  1016. xchg ah,al
  1017. xor ah,ah
  1018. Debug_Out "GrowSFTToMax: At least 128 files handles required in CONFIG.SYS only specified #AX"
  1019. jmp ExitKernel
  1020. else
  1021. sub al,ah ;al has the no of extra handles
  1022. xor ah,ah ;ax has no of extra handles
  1023. mov NewHandles,ax ;save it.
  1024. mul FileEntrySize ;dx:ax has size of table
  1025. add ax,(SIZE SFT) - 1 ;size of the initial header
  1026. mov NewTableSize,ax ;save size
  1027. regptr dxax,dx,ax
  1028. save <es,bx>
  1029. cCall GlobalDOSAlloc,<dxax> ;allocate the block
  1030. jcxz GrowSFTToMaxRet ;no memory to allocate
  1031. cCall SetOwner,<ax,hExeHead>
  1032. ; store the pointer to the new link in the current link.
  1033. push bx ;save
  1034. mov bx,ax ;get the new selector
  1035. call GetSelectorSegment ;returns segment of sel in ax, in dx
  1036. pop bx ;restore
  1037. mov word ptr es:[bx].sftLink[2],dx
  1038. mov word ptr es:[bx].sftLink[0],0
  1039. ; we have to save the address of this last original link so that it can be
  1040. ; restored to be the last at DisableKernel time. We will save the current
  1041. ; selector and delete it at disable time
  1042. mov word ptr [pSftLink],bx ;save
  1043. mov word ptr [pSftLink+2],es
  1044. mov bx,es ;get the selector
  1045. mov es,ax ;es points to new link
  1046. ; initialize memory tp all zeros
  1047. xor di,di ;es:di points to new buffer
  1048. mov cx,NewTableSize ;size of buffer
  1049. xor al,al ;want to initialize to 0's
  1050. rep stosb ;initialized
  1051. ; prepare the header for the new table.
  1052. xor bx,bx ;es:bx points to the new table
  1053. mov cx,-1 ;link terminator code
  1054. mov word ptr es:[bx].sftLink[2],cx
  1055. mov word ptr es:[bx].sftLink[0],cx
  1056. mov cx,NewHandles ;# of handles in this node
  1057. mov es:[bx].sftCount,cx
  1058. endif; WOW
  1059. GrowSFTToMaxRet:
  1060. cEnd
  1061. ;----------------------------------------------------------------------------;
  1062. ; SetSelectorBaseLim64k: ;
  1063. ; ;
  1064. ; Given a selector value in bx and a real mode lptr in cx:dx, it sets the ba-;
  1065. ; -se of the selector to that value and sets it to be a 64k data segment. AX ;
  1066. ; is preserved. ;
  1067. ; ;
  1068. ;----------------------------------------------------------------------------;
  1069. SetSelectorBaseLim64k proc near
  1070. push ax ;save
  1071. ; calculate the linear base address.
  1072. xor ax,ax ;will have high nibble of shift
  1073. shl cx,1 ;shift by 1
  1074. rcl ax,1 ;gather in
  1075. shl cx,1 ;shift by 1
  1076. rcl ax,1 ;gather in
  1077. shl cx,1 ;shift by 1
  1078. rcl ax,1 ;gather in
  1079. shl cx,1 ;shift by 1
  1080. rcl ax,1 ;gather in
  1081. add cx,dx ;add in the offset
  1082. adc ax,0 ;ax:cx has the base
  1083. mov dx,cx ;get into proper registers
  1084. mov cx,ax ;cx:dx has the base
  1085. mov ax,7 ;set selector base code
  1086. int 31h ;the base of the selector has been set
  1087. inc ax ;set selector limit code
  1088. mov dx,-1 ;64-1k limit
  1089. xor cx,cx ;cx:dx=64-1k
  1090. int 31h ;limit set to 64-1k
  1091. pop ax ;restore ax
  1092. ret
  1093. SetSelectorBaseLim64k endp
  1094. ;----------------------------------------------------------------------------;
  1095. ; GetSelectorSegment: ;
  1096. ; ;
  1097. ; Given a slector in bx pointing to DOS memory, this function returns the ;
  1098. ; real mode segment value in DX. AX,BX is preserved. ;
  1099. ;----------------------------------------------------------------------------;
  1100. GetSelectorSegment proc near
  1101. push ax ;save
  1102. push bx ;save
  1103. mov ax,6 ;get selector base
  1104. int 31h ;cx:dx has base
  1105. shr cx,1 ;shift by 1
  1106. rcr dx,1 ;gather into dx
  1107. shr cx,1 ;shift by 1
  1108. rcr dx,1 ;gather into dx
  1109. shr cx,1 ;shift by 1
  1110. rcr dx,1 ;gather into dx
  1111. shr cx,1 ;shift by 1
  1112. rcr dx,1 ;gather into dx
  1113. pop bx ;restore
  1114. pop ax ;dx has segment value
  1115. ret
  1116. GetSelectorSegment endp
  1117. ;----------------------------------------------------------------------------;
  1118. sEnd INITCODE
  1119. end