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.

335 lines
6.4 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. Buffer.c
  5. Abstract:
  6. This module contains routines to perform the actual buffering of data
  7. for dpmi api translation support.
  8. Author:
  9. Dave Hastings (daveh) 30-Nov-1992
  10. Revision History:
  11. Neil Sandlin (neilsa) 31-Jul-1995 - Updates for the 486 emulator
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. #include "softpc.h"
  16. #include "..\softpc.new\host\inc\host_rrr.h"
  17. #include "..\softpc.new\host\inc\nt_uis.h"
  18. PUCHAR
  19. DpmiMapAndCopyBuffer(
  20. PUCHAR Buffer,
  21. USHORT BufferLength
  22. )
  23. /*++
  24. Routine Description:
  25. This routine selects the appropriate buffer for the translation,
  26. and copies the high memory buffer to it.
  27. Arguments:
  28. Buffer -- Supplies buffer in high memory
  29. BufferLength -- Supplies the length of the buffer
  30. Return Value:
  31. Returns a pointer to the translation buffer
  32. --*/
  33. {
  34. PUCHAR NewBuffer;
  35. //
  36. // if the buffer is already in low memory, don't do anything
  37. //
  38. if ((ULONG)(Buffer + BufferLength - IntelBase) < MAX_V86_ADDRESS) {
  39. return Buffer;
  40. }
  41. NewBuffer = DpmiAllocateBuffer(BufferLength);
  42. CopyMemory(NewBuffer, Buffer, BufferLength);
  43. return NewBuffer;
  44. }
  45. VOID
  46. DpmiUnmapAndCopyBuffer(
  47. PUCHAR Destination,
  48. PUCHAR Source,
  49. USHORT BufferLength
  50. )
  51. /*++
  52. Routine Description:
  53. This routine copies the information back to the high memory buffer
  54. Arguments:
  55. Destination -- Supplies the destination buffer
  56. Source -- Supplies the source buffer
  57. BufferLength -- Supplies the length of the information to copy
  58. Return Value:
  59. None.
  60. --*/
  61. {
  62. //
  63. // If the addresses are the same, don't do anything
  64. //
  65. if (Source == Destination) {
  66. return;
  67. }
  68. CopyMemory(Destination, Source, BufferLength);
  69. //
  70. // Free the buffer
  71. //
  72. DpmiFreeBuffer(Source, BufferLength);
  73. }
  74. USHORT
  75. DpmiCalcFcbLength(
  76. PUCHAR FcbPointer
  77. )
  78. /*++
  79. Routine Description:
  80. This routine calculates the length of an FCB.
  81. Arguments:
  82. FcbPointer -- Supplies the Fcb
  83. Return Value:
  84. Length of the fcb in bytes
  85. --*/
  86. {
  87. if (*FcbPointer == 0xFF) {
  88. return 0x2c;
  89. } else {
  90. return 0x25;
  91. }
  92. }
  93. PUCHAR
  94. DpmiMapString(
  95. USHORT StringSeg,
  96. ULONG StringOff,
  97. PWORD16 Length
  98. )
  99. /*++
  100. Routine Description:
  101. This routine maps an asciiz string to low memory
  102. Arguments:
  103. StringSeg -- Supplies the segment of the string
  104. StringOff -- Supplies the offset of the string
  105. Return Value:
  106. Pointer to the buffered string or NULL in error case
  107. ; NOTE:
  108. ; DOS has a tendency to look one byte past the end of the string "\"
  109. ; to look for ":\" followed by a zero. For this reason, we always
  110. ; map three extra bytes of every string.
  111. --*/
  112. {
  113. USHORT CurrentChar = 0;
  114. PUCHAR String, NewString = NULL;
  115. ULONG Limit;
  116. BOOL SetNull = FALSE;
  117. String = VdmMapFlat(StringSeg, StringOff, VDM_PM);
  118. //
  119. // Scan string for NULL
  120. //
  121. GET_SHADOW_SELECTOR_LIMIT(StringSeg, Limit);
  122. if (Limit == 0 || StringOff >= Limit) {
  123. return NULL;
  124. }
  125. Limit -= StringOff;
  126. while (CurrentChar <= (USHORT)Limit) {
  127. if (String[CurrentChar] == '\0') {
  128. break;
  129. }
  130. CurrentChar++;
  131. }
  132. if (CurrentChar > (USHORT)Limit) {
  133. //
  134. // If we didn't find the end, move CurrentChar back to the end
  135. // of the segmen and only copy 100h bytes maximum.
  136. //
  137. SetNull = TRUE;
  138. CurrentChar--;
  139. if (CurrentChar > 0x100) {
  140. CurrentChar = 0x100;
  141. }
  142. }
  143. //
  144. // CurrentChar points to the last char that we need to copy and
  145. // most importantly CurrentChar is still within the segment.
  146. //
  147. ASSERT (CurrentChar <= (USHORT)Limit);
  148. //
  149. // If there are 3 bytes after the string, copy the extra 3 bytes
  150. //
  151. if ((CurrentChar + 3) <= (USHORT)Limit) {
  152. CurrentChar += 3;
  153. } else {
  154. CurrentChar = (USHORT)Limit;
  155. }
  156. //
  157. // The length is one based. The index is zero based
  158. //
  159. *Length = CurrentChar + 1;
  160. NewString = DpmiMapAndCopyBuffer(String, (USHORT) (CurrentChar + 1));
  161. if (SetNull) {
  162. NewString[CurrentChar] = '\0';
  163. }
  164. return NewString;
  165. }
  166. PUCHAR
  167. DpmiAllocateBuffer(
  168. USHORT Length
  169. )
  170. /*++
  171. Routine Description:
  172. This routine allocates buffer space from the static buffer in low
  173. memory.
  174. Arguments:
  175. Length -- Length of the buffer needed
  176. Return Value:
  177. Returns pointer to the buffer space allocated
  178. Note, this routine never fails. If we are out of buffer space, this is
  179. considered as a BugCheck condition for NTVDM. NtVdm will be terminated.
  180. --*/
  181. {
  182. //
  183. // If the data fits in the small buffer, use it
  184. //
  185. if ((Length <= SMALL_XLAT_BUFFER_SIZE) && !SmallBufferInUse) {
  186. SmallBufferInUse = TRUE;
  187. return SmallXlatBuffer;
  188. }
  189. if (Length <= (LARGE_XLAT_BUFFER_SIZE - LargeBufferInUseCount)) {
  190. LargeBufferInUseCount += Length;
  191. return (LargeXlatBuffer + LargeBufferInUseCount - Length);
  192. }
  193. //
  194. // Whoops! No buffer space available.
  195. // This is an internal error. Terminate ntvdm.
  196. //
  197. ASSERT(0); // this is an internal error
  198. DisplayErrorTerm(EHS_FUNC_FAILED,GetLastError(),__FILE__,__LINE__);
  199. return (PUCHAR)0xf00df00d;
  200. }
  201. VOID
  202. DpmiFreeBuffer(
  203. PUCHAR Buffer,
  204. USHORT Length
  205. )
  206. /*++
  207. Routine Description:
  208. Frees buffer space allocated using DpmiAllocateBuffer
  209. Arguments:
  210. Buffer -- Supplies a pointer to the buffer allocated above
  211. Length -- Length of the buffer allocated
  212. Return Value:
  213. None.
  214. --*/
  215. {
  216. //
  217. // Free the buffer
  218. //
  219. if (Buffer == SmallXlatBuffer) {
  220. SmallBufferInUse = FALSE;
  221. }
  222. if ((Buffer >= LargeXlatBuffer) &&
  223. (Buffer < (LargeXlatBuffer + LARGE_XLAT_BUFFER_SIZE))
  224. ) {
  225. LargeBufferInUseCount -= Length;
  226. }
  227. }
  228. VOID
  229. DpmiFreeAllBuffers(
  230. VOID
  231. )
  232. /*++
  233. Routine Description:
  234. This routine frees all of the currently allocated buffer space.
  235. Arguments:
  236. Return Value:
  237. None.
  238. --*/
  239. {
  240. SmallBufferInUse = FALSE;
  241. LargeBufferInUseCount = 0;
  242. }