00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
00070 *pNtVDMState |= VDM_IDLEACTIVITY;
00071
00072
Status =
VdmpGetVdmTib(&VdmTib,
VDMTIB_KMODE);
00073
00074
if (!
NT_SUCCESS(
Status)) {
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
00084 hFile =
GETHANDLE((TrapFrame->Eax & 0x0000ffff),(TrapFrame->Ebp & 0x0000ffff));
00085
00086
00087
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
00101 lpBuf = (PVOID)
GETBUFFER(TrapFrame->V86Ds, (TrapFrame->Edx & 0x0000ffff));
00102
00103
00104 CountToIO = TrapFrame->Ecx & 0x0000ffff;
00105
00106
00107 ulBX = TrapFrame->Ebx & 0x0000ffff;
00108 ulSI = TrapFrame->Esi & 0x0000ffff;
00109
00110
00111
00112 OldIrql = KeGetCurrentIrql();
00113
KeLowerIrql(
PASSIVE_LEVEL);
00114
00115
try {
00116
00117
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
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;
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 }