Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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