NtReadFileScatter
NTSTATUS __stdcall NtReadFileScatter(
HANDLE FileHandle,
HANDLE Event,
PIO_APC_ROUTINE UserApcRoutine,
PVOID UserApcContext,
PIO_STATUS_BLOCK UserIoStatusBlock,
FILE_SEGMENT_ELEMENT BufferDescription[],
ULONG BufferLength,
PLARGE_INTEGER ByteOffset,
PULONG Key){
HANDLE v9;
PULONG v10;
INT8 v11;
NTSTATUS result;
__int64 v13;
_DEVICE_OBJECT *RelatedDeviceObject;
_DEVICE_OBJECT *v15;
int v16;
unsigned __int64 v17;
__int64 v18;
ULONG v19;
ULONG v20;
__int64 v21;
__int64 v22;
struct _DMA_ADAPTER *v23;
PLARGE_INTEGER v24;
unsigned int v25;
__int64 v26;
bool v27;
__int64 v28;
FILE_SEGMENT_ELEMENT *PoolWithQuota_0;
__int64 i;
__int16 v31;
UINT64 v32;
int v33;
UINT8 v34;
UINT8 v35;
struct _DMA_ADAPTER *v36;
int v37;
CHAR v38;
IRP *Irp;
IRP *v40;
PIO_STATUS_BLOCK v41;
__int64 v42;
ULONG v43;
MDL *Mdl;
FILE_SEGMENT_ELEMENT *__attribute__((__org_arrdim(0,0))) v45;
_DWORD *v46;
_ETHREAD *v47;
__int64 v48;
__int64 v49;
INT64 v50;
IRP *Object;
UINT64 v52;
KPROCESSOR_MODE AccessMode;
char v54[15];
PVOID P;
LONGLONG QuadPart;
ULONG v57;
int v58;
PADAPTER_OBJECT DmaAdapter;
PVOID VirtualAddress;
int v61;
PDEVICE_OBJECT DeviceObject;
_ETHREAD *CurrentThread;
_DWORD *v64;
_ETHREAD *v65;
VOID *retaddr;
INT64 v68;
PVOID v69;
v69 = UserApcContext;
v68 = (INT64)UserApcRoutine;
v9 = Event;
v10 = Key;
*(_QWORD *)&v54[7] = 0i64;
P = 0i64;
DmaAdapter = 0i64;
v57 = 0;
QuadPart = 0i64;
CurrentThread = (_ETHREAD *)KeGetCurrentThread();
v11 = *((_BYTE *)CurrentThread + 562);
AccessMode = v11;
result = IopReferenceFileObject(FileHandle, 1ui64, v11, (FILE_OBJECT **)&v54[7], 0i64);
if( result < 0 )
return result;
v13 = *(_QWORD *)&v54[7];
RelatedDeviceObject = IoGetRelatedDeviceObject(*(_FILE_OBJECT **)&v54[7]);
v15 = RelatedDeviceObject;
DeviceObject = RelatedDeviceObject;
v16 = *(_DWORD *)(v13 + 80);
if( (v16 & 8) == 0
|| (v16 & 2) != 0
|| (*((_DWORD *)RelatedDeviceObject + 12) & 4) != 0
|| ((v17 = *((unsigned int *)RelatedDeviceObject + 18), (unsigned int)v17 > 0x36)
|| (v18 = 0x40000100100348i64, !_bittest64(&v18, v17)))
&& (_DWORD)v17 != 83 )
{
HalPutDmaAdapter((PADAPTER_OBJECT)v13);
return -1073741811;
}
v19 = BufferLength;
v20 = (BufferLength >> 12) + ((BufferLength & 0xFFF) != 0);
if( v11 )
{
v58 = 0;
v21 = (__int64)UserIoStatusBlock;
v22 = 0x7FFFFFFF0000i64;
if( (unsigned __int64)UserIoStatusBlock >= 0x7FFFFFFF0000i64 )
v21 = 0x7FFFFFFF0000i64;
*(_DWORD *)v21 = *(_DWORD *)v21;
IopMarkApcRoutineIfAsynchronousIo32((UINT64 **)&UserIoStatusBlock, &v68, *(_BYTE *)(v13 + 80) & 2);
v23 = *(struct _DMA_ADAPTER **)&v54[7];
if( *(_QWORD *)(*(_QWORD *)&v54[7] + 176i64) && (v68 & 0xFFFFFFFFFFFFFFFEui64) != 0 )
{
HalPutDmaAdapter(*(PADAPTER_OBJECT *)&v54[7]);
return -1073741811;
}
v24 = ByteOffset;
if( ByteOffset )
{
if( ((unsigned __int8)ByteOffset & 3) != 0 )
ExRaiseDatatypeMisalignment();
QuadPart = ByteOffset->QuadPart;
v23 = *(struct _DMA_ADAPTER **)&v54[7];
}
if( (*(_DWORD *)(v13 + 80) & 8) != 0 )
{
if( (v25 = *((unsigned __int16 *)v15 + 152), (_WORD)v25) && ((v25 - 1) & v19) != 0 && v19 % v25
|| ByteOffset && (_WORD)v25 && ((v25 - 1) & (unsigned int)QuadPart) != 0 )
{
HalPutDmaAdapter(v23);
return -1073741811;
}
}
v65 = (_ETHREAD *)KeGetCurrentThread();
v26 = *(_QWORD *)(*((_QWORD *)v65 + 23) + 1408i64);
v27 = 0;
if( v26 )
{
v31 = *(_WORD *)(v26 + 8);
if( v31 == 332 || v31 == 452 )
v27 = 1;
}
v28 = v20;
if( v28 * 8 )
{
if( v27 )
{
if( ((unsigned __int8)BufferDescription & 3) != 0 )
ExRaiseDatatypeMisalignment();
}
else if( ((unsigned __int8)BufferDescription & 7) != 0 )
{
ExRaiseDatatypeMisalignment();
}
if( (unsigned __int64)&BufferDescription[v28] > 0x7FFFFFFF0000i64 || &BufferDescription[v28] < BufferDescription )
MEMORY[0x7FFFFFFF0000] = 0;
}
if( v19 )
{
PoolWithQuota_0 = (FILE_SEGMENT_ELEMENT *)IopVerifierExAllocatePoolWithQuota_0(PagedPool, 8i64 * v20);
P = PoolWithQuota_0;
memmove((UINT8 *)PoolWithQuota_0, (UINT8 *)BufferDescription, 8i64 * v20);
BufferDescription = PoolWithQuota_0;
for( i = 0i64; ; i = (unsigned int)(i + 1) )
{
v61 = i;
if( (unsigned int)i >= v20 )
break;
if( ((__int64)BufferDescription[i].Buffer & 0xFFFi64) != 0 )
RtlRaiseStatus(-1073741811);
}
}
else
{
PoolWithQuota_0 = (FILE_SEGMENT_ELEMENT *)P;
}
if( v10 )
{
if( (unsigned __int64)v10 < 0x7FFFFFFF0000i64 )
v22 = (__int64)v10;
v57 = *(_DWORD *)v22;
PoolWithQuota_0 = (FILE_SEGMENT_ELEMENT *)P;
}
v13 = *(_QWORD *)&v54[7];
v9 = Event;
}
else
{
v24 = ByteOffset;
if( ByteOffset )
QuadPart = ByteOffset->QuadPart;
PoolWithQuota_0 = (FILE_SEGMENT_ELEMENT *)P;
if( v10 )
v57 = *v10;
}
if( v9 )
{
VirtualAddress = 0i64;
v33 = ObReferenceObjectByHandle(v9, 2u, (POBJECT_TYPE)ExEventObjectType, AccessMode, &VirtualAddress, 0i64);
v36 = (struct _DMA_ADAPTER *)VirtualAddress;
DmaAdapter = (PADAPTER_OBJECT)VirtualAddress;
if( v33 < 0 )
{
HalPutDmaAdapter((PADAPTER_OBJECT)v13);
if( PoolWithQuota_0 )
ExFreePoolWithTag(PoolWithQuota_0, 0);
return v33;
}
KeResetEvent(VirtualAddress, v32, v34, v35, Object);
}
else
{
v36 = DmaAdapter;
}
v64 = (_DWORD *)(v13 + 80);
v37 = *(_DWORD *)(v13 + 80);
if( (v37 & 2) != 0 )
{
v47 = (_ETHREAD *)KeGetCurrentThread();
--*((_WORD *)v47 + 242);
v48 = *(_QWORD *)&v54[7];
LODWORD(v49) = KeAbPreAcquire((PVOID)(*(_QWORD *)&v54[7] + 128i64), 0i64, 0i64);
if( _InterlockedExchange((volatile __int32 *)(v48 + 116), 1) )
{
LOBYTE(v50) = AccessMode;
v13 = *(_QWORD *)&v54[7];
IopWaitAndAcquireFileObjectLock(*(PVOID *)&v54[7], v50);
}
else
{
if( v49 )
*(_BYTE *)(v49 + 26) |= 1u;
v13 = *(_QWORD *)&v54[7];
ObfReferenceObject(*(PVOID *)&v54[7]);
}
if( !v24 || QuadPart == -2 )
QuadPart = *(_QWORD *)(v13 + 104);
v38 = 1;
PoolWithQuota_0 = (FILE_SEGMENT_ELEMENT *)P;
v36 = DmaAdapter;
}
else
{
if( !v24 && (v37 & 0x280) == 0 )
{
if( v36 )
HalPutDmaAdapter(v36);
LABEL_100:
HalPutDmaAdapter((PADAPTER_OBJECT)v13);
if( PoolWithQuota_0 )
ExFreePoolWithTag(PoolWithQuota_0, 0);
return -1073741811;
}
v38 = 0;
}
if( QuadPart < 0 )
{
if( v36 )
HalPutDmaAdapter(v36);
if( v38 )
IopReleaseFileObjectLock((PADAPTER_OBJECT)v13);
goto LABEL_100;
}
IopResetEvent((FILE_OBJECT *)v13);
Irp = IopAllocateIrpExReturn(DeviceObject, *((_BYTE *)DeviceObject + 76), v38 ^ 1u, retaddr);
v40 = Irp;
VirtualAddress = Irp;
if( Irp )
{
*((_QWORD *)Irp + 24) = v13;
*((_QWORD *)Irp + 19) = CurrentThread;
*((_QWORD *)Irp + 20) = 0i64;
*((_BYTE *)Irp + 64) = AccessMode;
*((_BYTE *)Irp + 65) = 0;
*((_BYTE *)Irp + 68) = 0;
*((_QWORD *)Irp + 13) = 0i64;
*((_QWORD *)Irp + 10) = v36;
v41 = UserIoStatusBlock;
*((_QWORD *)Irp + 9) = UserIoStatusBlock;
*((_QWORD *)Irp + 11) = v68;
*((_QWORD *)Irp + 12) = v69;
v42 = *((_QWORD *)Irp + 23);
*(_DWORD *)(v42 - 72) = 3;
*(_QWORD *)(v42 - 24) = v13;
*((_QWORD *)Irp + 3) = 0i64;
*((_QWORD *)Irp + 1) = 0i64;
*((_DWORD *)Irp + 4) = 0;
v43 = BufferLength;
if( BufferLength )
{
Mdl = IoAllocateMdl(BufferDescription->Buffer, BufferLength, 0, 1u, Irp);
if( !Mdl )
RtlRaiseStatus(-1073741670);
v45 = BufferDescription;
MmProbeAndLockSelectedPages(Mdl, BufferDescription, AccessMode, IoWriteAccess);
*((FILE_SEGMENT_ELEMENT *)v40 + 14) = (FILE_SEGMENT_ELEMENT)v45->Buffer;
v43 = BufferLength;
}
if( PoolWithQuota_0 )
ExFreePoolWithTag(PoolWithQuota_0, 0);
*((_DWORD *)v40 + 4) |= (*v64 & 8 | 0x4800u) >> 3;
*(_DWORD *)(v42 - 64) = v43;
*(_DWORD *)(v42 - 56) = v57;
*(_QWORD *)(v42 - 48) = QuadPart;
v46 = *(_DWORD **)(v13 + 208);
if( v46 && (*v46 & 0x10) != 0 )
*(_DWORD *)(v42 - 52) = v41->Information;
LODWORD(v52) = 0;
return IopSynchronousServiceTail(DeviceObject, v40, (FILE_OBJECT *)v13, 1, AccessMode, v38, v52);
}
else
{
IopAllocateIrpCleanup((PUNICODE_STRING)v13);
if( PoolWithQuota_0 )
ExFreePoolWithTag(PoolWithQuota_0, 0);
return -1073741670;
}
}Referenced by:
No references.