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.

316 lines
5.3 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. PUCHAR
  17. DpmiMapAndCopyBuffer(
  18. PUCHAR Buffer,
  19. USHORT BufferLength
  20. )
  21. /*++
  22. Routine Description:
  23. This routine selects the appropriate buffer for the translation,
  24. and copies the high memory buffer to it.
  25. Arguments:
  26. Buffer -- Supplies buffer in high memory
  27. BufferLength -- Supplies the length of the buffer
  28. Return Value:
  29. Returns a pointer to the translation buffer
  30. --*/
  31. {
  32. PUCHAR NewBuffer;
  33. //
  34. // if the buffer is already in low memory, don't do anything
  35. //
  36. if ((ULONG)(Buffer + BufferLength - IntelBase) < MAX_V86_ADDRESS) {
  37. return Buffer;
  38. }
  39. NewBuffer = DpmiAllocateBuffer(BufferLength);
  40. CopyMemory(NewBuffer, Buffer, BufferLength);
  41. return NewBuffer;
  42. }
  43. VOID
  44. DpmiUnmapAndCopyBuffer(
  45. PUCHAR Destination,
  46. PUCHAR Source,
  47. USHORT BufferLength
  48. )
  49. /*++
  50. Routine Description:
  51. This routine copies the information back to the high memory buffer
  52. Arguments:
  53. Destination -- Supplies the destination buffer
  54. Source -- Supplies the source buffer
  55. BufferLength -- Supplies the length of the information to copy
  56. Return Value:
  57. None.
  58. --*/
  59. {
  60. //
  61. // If the addresses are the same, don't do anything
  62. //
  63. if (Source == Destination) {
  64. return;
  65. }
  66. CopyMemory(Destination, Source, BufferLength);
  67. //
  68. // Free the buffer
  69. //
  70. DpmiFreeBuffer(Source, BufferLength);
  71. }
  72. USHORT
  73. DpmiCalcFcbLength(
  74. PUCHAR FcbPointer
  75. )
  76. /*++
  77. Routine Description:
  78. This routine calculates the length of an FCB.
  79. Arguments:
  80. FcbPointer -- Supplies the Fcb
  81. Return Value:
  82. Length of the fcb in bytes
  83. --*/
  84. {
  85. if (*FcbPointer == 0xFF) {
  86. return 0x2c;
  87. } else {
  88. return 0x25;
  89. }
  90. }
  91. PUCHAR
  92. DpmiMapString(
  93. USHORT StringSeg,
  94. ULONG StringOff,
  95. PWORD16 Length
  96. )
  97. /*++
  98. Routine Description:
  99. This routine maps an asciiz string to low memory
  100. Arguments:
  101. StringSeg -- Supplies the segment of the string
  102. StringOff -- Supplies the offset of the string
  103. Return Value:
  104. Pointer to the buffered string
  105. ; NOTE:
  106. ; DOS has a tendency to look one byte past the end of the string "\"
  107. ; to look for ":\" followed by a zero. For this reason, we always
  108. ; map three extra bytes of every string.
  109. --*/
  110. {
  111. USHORT CurrentChar = 0;
  112. PUCHAR String;
  113. ULONG Limit;
  114. String = VdmMapFlat(StringSeg, StringOff, VDM_PM);
  115. //
  116. // Scan string for NULL
  117. //
  118. GET_SHADOW_SELECTOR_LIMIT(StringSeg, Limit);
  119. Limit -= StringOff;
  120. while (CurrentChar <= (USHORT)Limit) {
  121. if (String[CurrentChar] == '\0') {
  122. break;
  123. }
  124. CurrentChar++;
  125. }
  126. //
  127. // If we didn't reach the end of the segment, we stopped because
  128. // of the null, and need to include that in the string
  129. //
  130. if (CurrentChar < (USHORT)Limit) {
  131. CurrentChar++;
  132. }
  133. //
  134. // If we didn't find the end, copy 100h bytes
  135. //
  136. if ((String[CurrentChar] != '\0') && CurrentChar > 0x100) {
  137. CurrentChar = 0x100;
  138. }
  139. //
  140. // If there are 3 bytes after the string, copy the extra 3 bytes
  141. //
  142. if ((CurrentChar + 3) <= (USHORT)Limit) {
  143. CurrentChar += 3;
  144. }
  145. //
  146. // The length is one based. The index is zero based
  147. //
  148. *Length = CurrentChar + 1;
  149. return DpmiMapAndCopyBuffer(String, (USHORT) (CurrentChar + 1));
  150. }
  151. PUCHAR
  152. DpmiAllocateBuffer(
  153. USHORT Length
  154. )
  155. /*++
  156. Routine Description:
  157. This routine allocates buffer space from the static buffer in low
  158. memory.
  159. Arguments:
  160. Length -- Length of the buffer needed
  161. Return Value:
  162. Returns pointer to the buffer space allocated
  163. --*/
  164. {
  165. //
  166. // If the data fits in the small buffer, use it
  167. //
  168. if ((Length <= SMALL_XLAT_BUFFER_SIZE) && !SmallBufferInUse) {
  169. SmallBufferInUse = TRUE;
  170. return SmallXlatBuffer;
  171. }
  172. if (Length <= (LARGE_XLAT_BUFFER_SIZE - LargeBufferInUseCount)) {
  173. LargeBufferInUseCount += Length;
  174. return (LargeXlatBuffer + LargeBufferInUseCount - Length);
  175. }
  176. //
  177. // Whoops! No buffer space available. Bomb with a predictable
  178. // address.
  179. //
  180. ASSERT(0); // this is an internal error
  181. return (PUCHAR)0xf00df00d;
  182. }
  183. VOID
  184. DpmiFreeBuffer(
  185. PUCHAR Buffer,
  186. USHORT Length
  187. )
  188. /*++
  189. Routine Description:
  190. Frees buffer space allocated using DpmiAllocateBuffer
  191. Arguments:
  192. Buffer -- Supplies a pointer to the buffer allocated above
  193. Length -- Length of the buffer allocated
  194. Return Value:
  195. None.
  196. --*/
  197. {
  198. //
  199. // Free the buffer
  200. //
  201. if (Buffer == SmallXlatBuffer) {
  202. SmallBufferInUse = FALSE;
  203. }
  204. if ((Buffer >= LargeXlatBuffer) &&
  205. (Buffer < (LargeXlatBuffer + LARGE_XLAT_BUFFER_SIZE))
  206. ) {
  207. LargeBufferInUseCount -= Length;
  208. }
  209. }
  210. VOID
  211. DpmiFreeAllBuffers(
  212. VOID
  213. )
  214. /*++
  215. Routine Description:
  216. This routine frees all of the currently allocated buffer space.
  217. Arguments:
  218. Return Value:
  219. None.
  220. --*/
  221. {
  222. SmallBufferInUse = FALSE;
  223. LargeBufferInUseCount = 0;
  224. }
  225.