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.

216 lines
5.7 KiB

  1. ;/*
  2. ; * Microsoft Confidential
  3. ; * Copyright (C) Microsoft Corporation 1988 - 1991
  4. ; * All Rights Reserved.
  5. ; */
  6. ; Check for existence of a VDisk header. Check the beginning of the segment
  7. ; addressed by the INT 19 vector, and, if XMS is available to give us
  8. ; A20 toggling, check at the 1Mb boundary. We don't do the latter check
  9. ; if we can't do the A20 switch.
  10. ;
  11. ; Return the size of the VDisk if found.
  12. ;
  13. ; Checking for a VDISK header at 1Mb is currently disabled. This is because
  14. ; the XMS calls used to access the HMA will cause INT 15 memory to
  15. ; be claimed if there are currently no Himem or XMS users, and the MEM
  16. ; command shouldn't disturb the memory environment in that way.
  17. ; We rely on VDisk allocators to use the INT 19 approach to signal
  18. ; their memory usage. According to Ray Duncan, this may not be
  19. ; entirely reliable, but this is probably better than adding the
  20. ; code necessary to do lots of INT 15 block moves to interrogate
  21. ; the extended memory arena.
  22. CHECKXMS equ 0 ; set to non-zero to enable checking
  23. ; of the HMA for VDisk headers.
  24. .MODEL SMALL
  25. .CODE
  26. extrn _XMM_Installed :Near
  27. extrn _XMM_QueryA20 :Near
  28. extrn _XMM_EnableA20 :Near
  29. extrn _XMM_DisableA20 :Near
  30. ;----------------------------------------------------------------------------
  31. ;
  32. ; following piece of code will be moved into a para boundary. And the para
  33. ; address posted in seg of int 19h vector. Offset of int 19h will point to
  34. ; VDint19. This is to protect HMA from apps which use VDISK header method
  35. ; to determine free extended memory.
  36. ;
  37. ; For more details read "power programming" column by Ray Duncan in the
  38. ; May 30 1989 issue of PC Magazine (pp 377-388) [USING EXTENDED MEMORY,PART 1]
  39. ;
  40. ;----------------------------------------------------------------------------
  41. ;
  42. StartVDHead label byte
  43. ;
  44. ;-------------- what follows is a dummy device driver header (not used by DOS)
  45. ;
  46. dd 0 ; link to next device driver
  47. dw 8000h ; device attribute
  48. dw 0 ; strategy routine offset
  49. dw 0 ; interrupt routine offset
  50. db 1 ; number of units
  51. db 7 dup(0) ; reserved area
  52. VDiskSig1 db 'VDISK'
  53. VLEN1 equ ($-offset VDiskSig1)
  54. db ' V3.3' ; vdisk label
  55. db 15 dup (0) ; pad
  56. VDiskEnd1 dw 0 ; bits 0-15 of free HMA
  57. db 11h ; bits 16-23 of free HMA (1M + 64K)
  58. VDInt19:
  59. db 0eah ; jmp to old vector
  60. OldVDInt19 dd ? ; Saved int 19 vector
  61. EndVDHead label byte
  62. ;
  63. ;
  64. VDiskHMAHead db 0,0,0 ; non-bootable disk
  65. VDiskSig2 db 'VDISK'
  66. VLEN2 equ ($-offset VDiskSig2)
  67. db '3.3' ; OEM - signature
  68. dw 128 ; number of bytes/sector
  69. db 1 ; sectors/cluster
  70. dw 1 ; reserved sectors
  71. db 1 ; number of FAT copies
  72. dw 64 ; number of root dir entries
  73. dw 512 ; number of sectors
  74. db 0feh ; media descriptor
  75. dw 6 ; number of sectors/FAT
  76. dw 8 ; sectors per track
  77. dw 1 ; number of heads
  78. dw 0 ; number of hodden sectors
  79. VDiskEnd2 dw 440h ; Start of free HMA in K (1M+64K)
  80. EndVDiskHMAHead label byte
  81. ;
  82. ;
  83. ;----------------------------------------------------------------------------
  84. ;
  85. ; procedure : IsVDiskInstalled
  86. ;
  87. ; Checks for the presence of VDISK header at 1MB boundary
  88. ; & INT 19 vector. Returns number of Kb used as Vdisk
  89. ;
  90. ; Inputs : none
  91. ; Outputs : AX = size of VDisk in Kb, 0 if none found
  92. ; Uses : AX, CX
  93. ;
  94. ;----------------------------------------------------------------------------
  95. ;
  96. public _CheckVDisk
  97. _CheckVDisk proc near
  98. push bp
  99. push si ; Save regs
  100. push di
  101. push es
  102. push ds
  103. mov ax,3519h ; Get Int Vector 19h
  104. int 21h
  105. ; set registers for CMPS
  106. mov di, offset VDiskSig1 - offset StartVDHead
  107. mov cx, VLEN1
  108. push cs
  109. pop ds
  110. mov si, offset VDiskSig1
  111. rep cmpsb
  112. IF NOT CHECKXMS
  113. jnz cvd_NoDisk
  114. ELSE
  115. jnz cvd_checkXMS ; jump if we didn't find it
  116. ENDIF
  117. ;
  118. ; Get the first free address in Kb, and determine the number of Kb used
  119. ; above 1Mb. First free address in a 24-bit address, so divide by 1024
  120. ; to get number of Kb
  121. ;
  122. mov di,offset VDiskEnd1 - offset StartVDHead
  123. mov ax,es:[di]+1 ; load top 16 bits of end address
  124. shr ax,1
  125. shr ax,1 ; fast divide of 24 bits by 1024
  126. test es:[di],03FFh ; check for rounding
  127. jz @F
  128. inc ax ; round up if needed
  129. @@:
  130. IF NOT CHECKXMS
  131. jmp short cvd_End
  132. ELSE
  133. pop ds ; clear top of stack
  134. jmp short cvd_End ; AX now has size in Kb
  135. ;
  136. ; Ensure that A20 is on before we check above 1Mb. If XMS is not
  137. ; installed, we punt, and assume no VDisk
  138. ;
  139. cvd_checkXMS:
  140. pop ds ; get DS again
  141. call _XMM_Installed
  142. or ax,ax
  143. jz cvd_NoDisk ; No XMS, assume no VDisk
  144. ;
  145. ; Get and save current A20 state, get A20 on
  146. ;
  147. call _XMM_QueryA20
  148. push ax ; save current state
  149. or ax,ax ; already on?
  150. jnz cvd_A20On ; yes, don't turn it on
  151. call _XMM_EnableA20 ; turn it on
  152. cvd_A20On:
  153. push ds ; save DS again
  154. mov ax, 0ffffh
  155. mov ds, ax
  156. mov si, 10h+(offset VDiskSig2 - offset VDiskHMAHead)
  157. mov ax,cs
  158. mov es,ax
  159. mov di, offset VDiskSig2
  160. mov cx, VLEN2
  161. rep cmpsb
  162. jne @F ; if no header, turn off A20 now
  163. ; get first free address in Kb
  164. mov si,offset VDiskEnd2 - offset VDiskHMAHead
  165. mov ax,[si]
  166. @@:
  167. pop ds ; get original DS again
  168. pop ax ; get original A20 state
  169. pushf ; save result of header check
  170. or ax,ax ; was A20 already on?
  171. jnz @F ; jump if yes
  172. call _XMM_DisableA20 ; else turn it off again
  173. @@:
  174. popf ; get result of header check
  175. je cvd_End ; jump if present
  176. ENDIF ; CHECKXMS
  177. cvd_NoDisk:
  178. mov ax,1024 ; set up to return 0
  179. cvd_End:
  180. sub ax,1024 ; discount first 1Mb from first
  181. ; free address to get size in Kb
  182. IF NOT CHECKXMS
  183. pop ds
  184. ENDIF
  185. pop es
  186. pop di
  187. pop si
  188. pop bp
  189. ret
  190. _CheckVDisk endp
  191. end
  192.