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.

317 lines
9.4 KiB

  1. IFDEF DBLSPACE_LEGAL
  2. page ,130
  3. title DeCompressor
  4. ;-----------------------------------------------------------------------
  5. ; Name: RDCOMP.ASM
  6. ;
  7. ; Routines defined:
  8. ; Decompress32
  9. ;
  10. ; Description:
  11. ; This file holds the code that is responsible for decompressing
  12. ; the compressed data.
  13. ;
  14. ; VxD History:
  15. ; 22-Apr-93 jeffpar Major adaptation and cleanup for MRCI32.386
  16. ;-----------------------------------------------------------------------
  17. .386p
  18. .xlist
  19. ;; include vmm.inc
  20. ;; include debug.inc
  21. include mdequ.inc
  22. .list
  23. MD_STAMP equ "SD"
  24. ;;;-----------------------------------------------------------------------
  25. ;;; Data segment
  26. ;;;-----------------------------------------------------------------------
  27. ;;
  28. ;;VxD_LOCKED_DATA_SEG
  29. ;;
  30. ;; public pLowerBound
  31. ;;pLowerBound dd 0 ; if non-zero, then this is the lowest linear
  32. ;; ; address we treat as *our* error
  33. ;; public pUpperBound
  34. ;;pUpperBound dd 0 ; if non-zero, then this is the highest linear
  35. ;; ; address we treat as *our* error (plus one)
  36. ;; public pPrevPgFltHdlr
  37. ;;pPrevPgFltHdlr dd 0 ; if non-zero, addr of previous page fault hdlr
  38. ;;
  39. ;;VxD_LOCKED_DATA_ENDS
  40. ;;
  41. ;;
  42. ;;VxD_PAGEABLE_DATA_SEG
  43. _DATA SEGMENT DWORD PUBLIC 'DATA'
  44. include decode.inc ; include macros and tables used for decoding
  45. public decode_data_end
  46. decode_data_end label byte
  47. ;;VxD_PAGEABLE_DATA_ENDS
  48. _DATA ENDS
  49. ;-----------------------------------------------------------------------
  50. ; Code segment
  51. ;-----------------------------------------------------------------------
  52. ;;VxD_PAGEABLE_CODE_SEG
  53. _TEXT SEGMENT DWORD USE32 PUBLIC 'CODE'
  54. ASSUME CS:FLAT, DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  55. public aCmdAt
  56. aCmdAt dd CmdAt0,CmdAt1,CmdAt2,CmdAt3,CmdAt4,CmdAt5,CmdAt6,CmdAt7
  57. ;-----------------------------------------------------------------------
  58. ; Decompression Algorithm
  59. ; -----------------------
  60. ; Decode the next chunk of text in 'coding_buffer', into the buffer as
  61. ; stated in the 'init'.
  62. ;
  63. ; Entry:
  64. ; CLD
  65. ; EBX == start of cluster (see MRCI32IncDecompress!)
  66. ; ECX == chunk count
  67. ; ESI -> compressed data
  68. ; EDI -> destination buffer
  69. ; EDX == remaining data(low)/bits(high) from last call, 0 if none
  70. ;
  71. ; Exit:
  72. ; If successful, CY clear and:
  73. ; ESI == offset to next byte uncompressed data (if any)
  74. ; EDI == offset to next free byte in dest buffer
  75. ; EDX == remaining data(low)/bits(high) for next call, 0 if none
  76. ;
  77. ; Uses:
  78. ; Everything except EBP
  79. ;-----------------------------------------------------------------------
  80. ;;BeginProc Decompress32
  81. public Decompress32
  82. Decompress32 proc near
  83. push ebp
  84. push ebp ; [esp] is our "chunk_count"
  85. ;; push ebx
  86. sub ebx,MAX_12BIT_OFFSET ;
  87. ;; mov [pLowerBound],ebx ;
  88. ;; pop [pUpperBound] ; fault handler enabled *now*
  89. mov eax,edx ; remaining data to AX
  90. shr edx,16 ; move state to low word of EDX
  91. jnz short @F ; jump if continuing previous state
  92. lodsw ; new decompression, load initial data
  93. @@: mov [esp],ecx ; save chunk count
  94. DecodeLoop:
  95. ;
  96. ; AX has the remaining bits, DL has the next state
  97. ;
  98. mov ebp,cbCHUNK ; (ebp) is # bytes left this chunk
  99. DecodeRestart
  100. LastErrSJump equ <FirstErrSJump>
  101. FirstErrSJump: jmp DecodeError ; put first nice fat jump out of the way
  102. irpc c,<01234567>
  103. CmdAt c
  104. endm
  105. jmp CmdAt0
  106. irpc c,<01234567>
  107. LengthAt c
  108. endm
  109. DoGeneralLength ; generate code here to handle large lengths
  110. DecodeDone:
  111. ;
  112. ; AX has the remaining bits, DL has the next state -- check chunk status
  113. ;
  114. test ebp,ebp ; perfect chunk-size decompression?
  115. jnz DecodeCheckLast ; no, check for last chunk
  116. dec dword ptr [esp] ; chunks remaining?
  117. jz DecodeSuccess ; no, so we're all done
  118. jmp DecodeLoop ; yes, process them
  119. public DecodeError
  120. DecodeError label near
  121. stc ; random decomp failure jump target
  122. jmp short DecodeExit
  123. DecodeCheckLast:
  124. dec dword ptr [esp] ; chunks remaining?
  125. jnz DecodeError ; yes, then we have an error
  126. DecodeSuccess:
  127. mov dh,1 ; return non-0 EDX indicating state exists
  128. shl edx,16 ; move state to high word of EDX
  129. movzx eax,ax ; make sure high word of EAX is clear
  130. or edx,eax ; EDX == state (and carry is CLEAR)
  131. DecodeExit:
  132. ;; mov [pUpperBound],0 ; fault handler disabled *now*
  133. ;; mov [pLowerBound],0 ;
  134. pop ebp ; throw away our "chunk_count" at [esp]
  135. pop ebp
  136. ret
  137. ;;EndProc Decompress32
  138. Decompress32 endp
  139. ;;VxD_PAGEABLE_CODE_ENDS
  140. _TEXT ENDS
  141. ;;
  142. ;;VxD_LOCKED_CODE_SEG
  143. ;;
  144. ;;;-----------------------------------------------------------------------
  145. ;;; Decompress32_Page_Fault
  146. ;;; -----------------------
  147. ;;; Looks for VMM page faults caused by the decompressor. The fault
  148. ;;; must have taken place in the range from [pLowerBound] to [pUpperBound]-1.
  149. ;;; If the fault IS in that range, then we set EIP to DecodeError.
  150. ;;;
  151. ;;; WARNING: this takes advantage of the fact that the decompressor does not
  152. ;;; use the stack; otherwise, we would obviously need to record and re-set ESP
  153. ;;; to a known point as well.
  154. ;;;
  155. ;;; This is in locked code to insure that a subsequent fault doesn't destroy
  156. ;;; the information necessary to process the first (eg, CR2)!
  157. ;;;
  158. ;;; Entry:
  159. ;;; EBX == VM handle
  160. ;;; EBP -> VMM re-entrant stack frame
  161. ;;;
  162. ;;; Uses:
  163. ;;; May use everything except SEG REGS
  164. ;;;-----------------------------------------------------------------------
  165. ;;
  166. ;;BeginProc Decompress32_Page_Fault
  167. ;;;
  168. ;;; Note: the fall-through case is the common one (ie, not our page fault)
  169. ;;;
  170. ;; push eax
  171. ;; mov eax,cr2 ; get faulting address
  172. ;; cmp eax,[pUpperBound]
  173. ;; jb short dpf_maybe ; it might be ours
  174. ;; ; otherwise, definitely not
  175. ;;dpf_prev:
  176. ;; pop eax ; we've been told to preserve everything
  177. ;; jmp [pPrevPgFltHdlr] ; dispatch to real page fault handler
  178. ;; ; (if we installed, then there *is* one)
  179. ;;dpf_maybe:
  180. ;; cmp eax,[pLowerBound]
  181. ;; jb short dpf_prev ; not going to "fix" it
  182. ;;
  183. ;; Trace_Out "Decompress32_Page_Fault: correcting fault on bad cluster"
  184. ;;
  185. ;; mov [ebp].Client_EIP,OFFSET32 DecodeError
  186. ;; pop eax
  187. ;; ret ; we "fixed" it
  188. ;;
  189. ;;EndProc Decompress32_Page_Fault
  190. ;;
  191. ;;VxD_LOCKED_CODE_ENDS
  192. ;++
  193. ;
  194. ; ULONG
  195. ; DblsMrcfDecompress (
  196. ; PUCHAR UncompressedBuffer,
  197. ; ULONG UncompressedLength,
  198. ; PUCHAR CompressedBuffer,
  199. ; ULONG CompressedLength,
  200. ; PMRCF_DECOMPRESS WorkSpace
  201. ; )
  202. ;
  203. ; Routine Description:
  204. ;
  205. ; This routine decompresses a buffer of StandardCompressed or MaxCompressed
  206. ; data.
  207. ;
  208. ; Arguments:
  209. ;
  210. ; UncompressedBuffer - buffer to receive uncompressed data
  211. ;
  212. ; UncompressedLength - length of UncompressedBuffer
  213. ;
  214. ; NOTE: UncompressedLength must be the EXACT length of the uncompressed
  215. ; data, as Decompress uses this information to detect
  216. ; when decompression is complete. If this value is
  217. ; incorrect, Decompress may crash!
  218. ;
  219. ; CompressedBuffer - buffer containing compressed data
  220. ;
  221. ; CompressedLength - length of CompressedBuffer
  222. ;
  223. ; WorkSpace - pointer to a private work area for use by this operation
  224. ;
  225. ; Return Value:
  226. ;
  227. ; ULONG - Returns the size of the decompressed data in bytes. Returns 0 if
  228. ; there was an error in the decompress.
  229. ;--
  230. _TEXT SEGMENT DWORD USE32 PUBLIC 'CODE'
  231. ASSUME CS:FLAT, DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  232. public _DblsMrcfDecompress@20
  233. _DblsMrcfDecompress@20 proc near
  234. push esi
  235. push edi
  236. push ebx
  237. mov ecx,dword ptr [esp+20]
  238. mov edx,ecx
  239. shr ecx,9
  240. and edx,512-1
  241. jz @f
  242. inc ecx
  243. sub edx,edx
  244. @@: mov esi,dword ptr [esp+24]
  245. mov edi,dword ptr [esp+16]
  246. mov ebx,edi
  247. cld
  248. lodsd
  249. cmp ax,MD_STAMP
  250. je @f
  251. sub eax,eax
  252. jz done
  253. @@: call Decompress32
  254. jnc @f
  255. sub eax,eax
  256. jz done
  257. @@: sub edi,dword ptr [esp+16]
  258. mov eax,edi
  259. done:
  260. pop ebx
  261. pop edi
  262. pop esi
  263. ret 20
  264. _DblsMrcfDecompress@20 endp
  265. _TEXT ENDS
  266. ENDIF ; DEF DBLSPACE_LEGAL
  267. end