Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

rdwr.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1992 Microsoft Corporation 00004 00005 Module Name: 00006 00007 rdwr.c 00008 00009 Abstract: 00010 00011 This module contains routines for read and write for NTDOS. These 00012 routines saves the switch to user mode. The BOP is handled in the 00013 kernel for performance reasons. These routines are called only for 00014 files. Local DOS devices and named pipe operations never come here. 00015 00016 Author: 00017 00018 Sudeep Bharati (Sudeepb) 04-Mar-1993 00019 00020 Revision History: 00021 00022 04-Mar-1993 sudeepb Created 00023 --*/ 00024 #include "vdmp.h" 00025 00026 VOID 00027 NTFastDOSIO ( 00028 PKTRAP_FRAME TrapFrame, 00029 ULONG IoType 00030 ); 00031 00032 #ifdef ALLOC_PRAGMA 00033 #pragma alloc_text(PAGE,NTFastDOSIO) 00034 #endif 00035 00036 #define EFLAGS_CF 0x1 00037 #define EFLAGS_ZF 0x40 00038 #define GETFILEPOINTER(hi,lo) (((ULONG)hi << 16) + (ULONG)lo) 00039 #define GETHANDLE(hi,lo) (HANDLE)(((ULONG)hi << 16) + (ULONG)lo) 00040 #define GETBUFFER(hi,lo) (((ULONG)hi << 4) + lo) 00041 #define SVC_DEMFASTREAD 0x42 00042 #define SVC_DEMFASTWRITE 0x43 00043 #define CONSOLE_HANDLE_SIGNATURE 0x00000003 00044 #define CONSOLE_HANDLE(HANDLE) (((ULONG)(HANDLE) & CONSOLE_HANDLE_SIGNATURE) == CONSOLE_HANDLE_SIGNATURE) 00045 #define STD_INPUT_HANDLE (ULONG)-10 00046 #define STD_OUTPUT_HANDLE (ULONG)-11 00047 #define STD_ERROR_HANDLE (ULONG)-12 00048 00049 VOID 00050 NTFastDOSIO ( 00051 PKTRAP_FRAME TrapFrame, 00052 ULONG IoType 00053 ) 00054 { 00055 HANDLE hFile; 00056 PVOID lpBuf; 00057 ULONG ulBX,ulSI; 00058 LARGE_INTEGER Large; 00059 PIO_STATUS_BLOCK IoStatusBlock; 00060 PFILE_POSITION_INFORMATION CurrentPosition; 00061 NTSTATUS Status; 00062 ULONG CountToIO; 00063 PFILE_END_OF_FILE_INFORMATION EndOfFile; 00064 PVDM_TIB VdmTib; 00065 KIRQL OldIrql; 00066 00067 PAGED_CODE(); 00068 00069 // signal softpc that we are doing disk io for idle detection 00070 *pNtVDMState |= VDM_IDLEACTIVITY; 00071 00072 Status = VdmpGetVdmTib(&VdmTib, VDMTIB_KMODE); // no probe, valid user-mode 00073 // address there 00074 if (!NT_SUCCESS(Status)) { // vdmtib is bad 00075 TrapFrame->EFlags |= EFLAGS_CF; 00076 return; 00077 } 00078 00079 IoStatusBlock = (PIO_STATUS_BLOCK) &VdmTib->TempArea1; 00080 CurrentPosition = (PFILE_POSITION_INFORMATION) &VdmTib->TempArea2; 00081 EndOfFile = (PFILE_END_OF_FILE_INFORMATION) CurrentPosition; 00082 00083 // Get the NT handle 00084 hFile = GETHANDLE((TrapFrame->Eax & 0x0000ffff),(TrapFrame->Ebp & 0x0000ffff)); 00085 00086 // advance ip past the bop instruction 00087 // clear carry flag, assuming success 00088 TrapFrame->Eip += 4; 00089 TrapFrame->EFlags &= ~EFLAGS_CF; 00090 00091 if (CONSOLE_HANDLE(hFile) || 00092 hFile == (HANDLE) STD_INPUT_HANDLE || 00093 hFile == (HANDLE) STD_OUTPUT_HANDLE || 00094 hFile == (HANDLE) STD_ERROR_HANDLE ) 00095 { 00096 TrapFrame->EFlags |= EFLAGS_CF; 00097 return; 00098 } 00099 00100 // Get the IO buffer 00101 lpBuf = (PVOID) GETBUFFER(TrapFrame->V86Ds, (TrapFrame->Edx & 0x0000ffff)); 00102 00103 // Get the Count 00104 CountToIO = TrapFrame->Ecx & 0x0000ffff; 00105 00106 // Get Seek Parameters 00107 ulBX = TrapFrame->Ebx & 0x0000ffff; 00108 ulSI = TrapFrame->Esi & 0x0000ffff; 00109 00110 00111 // Lower Irql to passive level for io system 00112 OldIrql = KeGetCurrentIrql(); 00113 KeLowerIrql(PASSIVE_LEVEL); 00114 00115 try { 00116 00117 // Check if we need to seek 00118 if (!(TrapFrame->EFlags & EFLAGS_ZF)) { 00119 Large = RtlConvertUlongToLargeInteger(GETFILEPOINTER(ulBX,ulSI)); 00120 CurrentPosition->CurrentByteOffset = Large; 00121 00122 Status = NtSetInformationFile( 00123 hFile, 00124 IoStatusBlock, 00125 CurrentPosition, 00126 sizeof(FILE_POSITION_INFORMATION), 00127 FilePositionInformation 00128 ); 00129 if (!NT_SUCCESS(Status) || 00130 CurrentPosition->CurrentByteOffset.LowPart == -1 ) 00131 { 00132 goto ErrorExit; 00133 } 00134 } 00135 00136 if (IoType == SVC_DEMFASTREAD){ 00137 Status = NtReadFile( 00138 hFile, 00139 NULL, 00140 NULL, 00141 NULL, 00142 IoStatusBlock, 00143 (PVOID)lpBuf, 00144 CountToIO, 00145 NULL, 00146 NULL 00147 ); 00148 } 00149 else{ 00150 if (CountToIO == 0) { 00151 Status = NtQueryInformationFile( 00152 hFile, 00153 IoStatusBlock, 00154 CurrentPosition, 00155 sizeof(FILE_POSITION_INFORMATION), 00156 FilePositionInformation 00157 ); 00158 if ( !NT_SUCCESS(Status) ) { 00159 goto ErrorExit; 00160 } 00161 00162 EndOfFile->EndOfFile = CurrentPosition->CurrentByteOffset; 00163 00164 Status = NtSetInformationFile( 00165 hFile, 00166 IoStatusBlock, 00167 EndOfFile, 00168 sizeof(FILE_END_OF_FILE_INFORMATION), 00169 FileEndOfFileInformation 00170 ); 00171 if ( NT_SUCCESS(Status) ){ 00172 KeRaiseIrql(OldIrql, &OldIrql); 00173 return; 00174 } 00175 00176 goto ErrorExit; 00177 } 00178 else { 00179 Status = NtWriteFile( 00180 hFile, 00181 NULL, 00182 NULL, 00183 NULL, 00184 IoStatusBlock, 00185 (PVOID)lpBuf, 00186 CountToIO, 00187 NULL, 00188 NULL 00189 ); 00190 } 00191 } 00192 00193 if ( Status == STATUS_PENDING) { 00194 // Operation must complete before return & IoStatusBlock destroyed 00195 Status = NtWaitForSingleObject( hFile, FALSE, NULL ); 00196 if ( NT_SUCCESS(Status)) { 00197 Status = IoStatusBlock->Status; 00198 } 00199 } 00200 00201 } 00202 except(ExSystemExceptionFilter()) { 00203 goto ErrorExit; // we have caught an exception, error exit 00204 } 00205 00206 00207 KeRaiseIrql(OldIrql, &OldIrql); 00208 00209 if ( NT_SUCCESS(Status) ) { 00210 TrapFrame->Eax &= 0xffff0000; 00211 TrapFrame->Eax |= (USHORT) IoStatusBlock->Information; 00212 } 00213 else if (IoType == SVC_DEMFASTREAD && Status == STATUS_END_OF_FILE) { 00214 TrapFrame->Eax &= 0xffff0000; 00215 } 00216 else { 00217 TrapFrame->EFlags |= EFLAGS_CF; 00218 } 00219 00220 return; 00221 00222 00223 ErrorExit: 00224 KeRaiseIrql(OldIrql, &OldIrql); 00225 TrapFrame->EFlags |= EFLAGS_CF; 00226 00227 return; 00228 }

Generated on Sat May 15 19:41:36 2004 for test by doxygen 1.3.7