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.

270 lines
7.1 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. rdwr.c
  5. Abstract:
  6. This module contains routines for read and write for NTDOS. These
  7. routines saves the switch to user mode. The BOP is handled in the
  8. kernel for performance reasons. These routines are called only for
  9. files. Local DOS devices and named pipe operations never come here.
  10. Author:
  11. Sudeep Bharati (Sudeepb) 04-Mar-1993
  12. Revision History:
  13. --*/
  14. #include "vdmp.h"
  15. VOID
  16. NTFastDOSIO (
  17. PKTRAP_FRAME TrapFrame,
  18. ULONG IoType
  19. );
  20. #ifdef ALLOC_PRAGMA
  21. #pragma alloc_text(PAGE,NTFastDOSIO)
  22. #endif
  23. #define EFLAGS_CF 0x1
  24. #define EFLAGS_ZF 0x40
  25. #define GETFILEPOINTER(hi,lo) (((ULONG)hi << 16) + (ULONG)lo)
  26. #define GETHANDLE(hi,lo) (HANDLE)(((ULONG)hi << 16) + (ULONG)lo)
  27. #define GETBUFFER(hi,lo) (((ULONG)hi << 4) + lo)
  28. #define SVC_DEMFASTREAD 0x42
  29. #define SVC_DEMFASTWRITE 0x43
  30. #define CONSOLE_HANDLE_SIGNATURE 0x00000003
  31. #define CONSOLE_HANDLE(HANDLE) (((ULONG)(HANDLE) & CONSOLE_HANDLE_SIGNATURE) == CONSOLE_HANDLE_SIGNATURE)
  32. #define STD_INPUT_HANDLE (ULONG)-10
  33. #define STD_OUTPUT_HANDLE (ULONG)-11
  34. #define STD_ERROR_HANDLE (ULONG)-12
  35. VOID
  36. NTFastDOSIO (
  37. PKTRAP_FRAME TrapFrame,
  38. ULONG IoType
  39. )
  40. {
  41. HANDLE hFile;
  42. PVOID lpBuf;
  43. ULONG ulBX,ulSI;
  44. LARGE_INTEGER Large;
  45. PIO_STATUS_BLOCK IoStatusBlock;
  46. PFILE_POSITION_INFORMATION CurrentPosition;
  47. NTSTATUS Status;
  48. ULONG CountToIO;
  49. PFILE_END_OF_FILE_INFORMATION EndOfFile;
  50. PVDM_TIB VdmTib;
  51. KIRQL OldIrql;
  52. PAGED_CODE();
  53. //
  54. // Signal softpc that we are doing disk io for idle detection.
  55. //
  56. try {
  57. *FIXED_NTVDMSTATE_LINEAR_PC_AT |= VDM_IDLEACTIVITY;
  58. }
  59. except (EXCEPTION_EXECUTE_HANDLER) {
  60. TrapFrame->EFlags |= EFLAGS_CF;
  61. return;
  62. }
  63. Status = VdmpGetVdmTib(&VdmTib);
  64. if (!NT_SUCCESS(Status)) { // vdmtib is bad
  65. TrapFrame->EFlags |= EFLAGS_CF;
  66. return;
  67. }
  68. IoStatusBlock = (PIO_STATUS_BLOCK) &VdmTib->TempArea1;
  69. CurrentPosition = (PFILE_POSITION_INFORMATION) &VdmTib->TempArea2;
  70. EndOfFile = (PFILE_END_OF_FILE_INFORMATION) CurrentPosition;
  71. try {
  72. ProbeForWrite (IoStatusBlock, sizeof (IO_STATUS_BLOCK), sizeof (UCHAR));
  73. ProbeForWrite (CurrentPosition, sizeof (FILE_END_OF_FILE_INFORMATION), sizeof (UCHAR));
  74. }
  75. except (EXCEPTION_EXECUTE_HANDLER) {
  76. TrapFrame->EFlags |= EFLAGS_CF;
  77. return;
  78. }
  79. // Get the NT handle
  80. hFile = GETHANDLE((TrapFrame->Eax & 0x0000ffff),(TrapFrame->Ebp & 0x0000ffff));
  81. // advance ip past the bop instruction
  82. // clear carry flag, assuming success
  83. TrapFrame->Eip += 4;
  84. TrapFrame->EFlags &= ~EFLAGS_CF;
  85. if (CONSOLE_HANDLE(hFile) ||
  86. hFile == (HANDLE) STD_INPUT_HANDLE ||
  87. hFile == (HANDLE) STD_OUTPUT_HANDLE ||
  88. hFile == (HANDLE) STD_ERROR_HANDLE )
  89. {
  90. TrapFrame->EFlags |= EFLAGS_CF;
  91. return;
  92. }
  93. // Get the IO buffer
  94. lpBuf = (PVOID) GETBUFFER(TrapFrame->V86Ds, (TrapFrame->Edx & 0x0000ffff));
  95. // Get the Count
  96. CountToIO = TrapFrame->Ecx & 0x0000ffff;
  97. // Get Seek Parameters
  98. ulBX = TrapFrame->Ebx & 0x0000ffff;
  99. ulSI = TrapFrame->Esi & 0x0000ffff;
  100. //
  101. // Lower Irql to PASSIVE_LEVEL for io system
  102. //
  103. OldIrql = KeGetCurrentIrql();
  104. KeLowerIrql (PASSIVE_LEVEL);
  105. //
  106. // Check if we need to seek
  107. //
  108. if (!(TrapFrame->EFlags & EFLAGS_ZF)) {
  109. Large = RtlConvertUlongToLargeInteger(GETFILEPOINTER(ulBX,ulSI));
  110. try {
  111. CurrentPosition->CurrentByteOffset = Large;
  112. }
  113. except(ExSystemExceptionFilter()) {
  114. goto ErrorExit; // we have caught an exception, error exit
  115. }
  116. Status = NtSetInformationFile (hFile,
  117. IoStatusBlock,
  118. CurrentPosition,
  119. sizeof(FILE_POSITION_INFORMATION),
  120. FilePositionInformation);
  121. if (!NT_SUCCESS(Status)) {
  122. goto ErrorExit;
  123. }
  124. try {
  125. if (CurrentPosition->CurrentByteOffset.LowPart == -1) {
  126. goto ErrorExit;
  127. }
  128. } except (ExSystemExceptionFilter()) {
  129. goto ErrorExit;
  130. }
  131. }
  132. if (IoType == SVC_DEMFASTREAD) {
  133. Status = NtReadFile (hFile,
  134. NULL,
  135. NULL,
  136. NULL,
  137. IoStatusBlock,
  138. (PVOID)lpBuf,
  139. CountToIO,
  140. NULL,
  141. NULL);
  142. }
  143. else {
  144. if (CountToIO == 0) {
  145. Status = NtQueryInformationFile (hFile,
  146. IoStatusBlock,
  147. CurrentPosition,
  148. sizeof(FILE_POSITION_INFORMATION),
  149. FilePositionInformation);
  150. if (!NT_SUCCESS(Status)) {
  151. goto ErrorExit;
  152. }
  153. try {
  154. EndOfFile->EndOfFile = CurrentPosition->CurrentByteOffset;
  155. }
  156. except(ExSystemExceptionFilter()) {
  157. goto ErrorExit; // we have caught an exception, error exit
  158. }
  159. Status = NtSetInformationFile (hFile,
  160. IoStatusBlock,
  161. EndOfFile,
  162. sizeof(FILE_END_OF_FILE_INFORMATION),
  163. FileEndOfFileInformation);
  164. if (NT_SUCCESS(Status)) {
  165. KeRaiseIrql(OldIrql, &OldIrql);
  166. return;
  167. }
  168. goto ErrorExit;
  169. }
  170. Status = NtWriteFile (hFile,
  171. NULL,
  172. NULL,
  173. NULL,
  174. IoStatusBlock,
  175. (PVOID)lpBuf,
  176. CountToIO,
  177. NULL,
  178. NULL);
  179. }
  180. if (Status == STATUS_PENDING) {
  181. //
  182. // Operation must complete before return & IoStatusBlock destroyed
  183. //
  184. Status = NtWaitForSingleObject (hFile, FALSE, NULL);
  185. if ( NT_SUCCESS(Status)) {
  186. try {
  187. Status = IoStatusBlock->Status;
  188. } except (ExSystemExceptionFilter()) {
  189. NOTHING;
  190. }
  191. }
  192. }
  193. KeRaiseIrql(OldIrql, &OldIrql);
  194. if ( NT_SUCCESS(Status) ) {
  195. TrapFrame->Eax &= 0xffff0000;
  196. try {
  197. TrapFrame->Eax |= (USHORT) IoStatusBlock->Information;
  198. } except (EXCEPTION_EXECUTE_HANDLER) {
  199. NOTHING;
  200. }
  201. }
  202. else if (IoType == SVC_DEMFASTREAD && Status == STATUS_END_OF_FILE) {
  203. TrapFrame->Eax &= 0xffff0000;
  204. }
  205. else {
  206. TrapFrame->EFlags |= EFLAGS_CF;
  207. }
  208. return;
  209. ErrorExit:
  210. KeRaiseIrql(OldIrql, &OldIrql);
  211. TrapFrame->EFlags |= EFLAGS_CF;
  212. return;
  213. }