VfGetScatterGatherList

NTSTATUS __stdcall VfGetScatterGatherList(
        _DMA_ADAPTER *DmaAdapter,
        INT64 a2,
        _MDL *a3,
        VOID *a4,
        INT64 Length,
        INT64 a6,
        INT64 a7,
        CHAR WriteToDevice){
  VOID *v8; 
  _MDL *v9; 
  _QWORD *v11; 
  __int64(__fastcall *RealDmaOperation)(_DMA_ADAPTER *, INT64, _MDL *, VOID *, unsigned int, INT64, INT64, CHAR); 
  INT64 v13; 
  _LIST_ENTRY *AdapterInformationInternal; 
  unsigned int v15; 
  __int64 v16; 
  ULONG_PTR v18; 
  ULONG_PTR v19; 
  _QWORD *v20; 
  INT64 v21; 
  int ByteOffset; 
  INT64 v23; 
  _MDL *v24; 
  unsigned int v25; 
  unsigned int ByteCount; 
  int v27; 
  int v28; 
  unsigned int v29; 
  UINT64 v30; 
  _MAP_REGISTER_FILE *v31; 
  _MAP_REGISTER_FILE *v32; 
  _OWORD *v33; 
  INT64 v34; 
  int v35; 
  NTSTATUS v36; 
  UINT64 *v37; 
  unsigned __int64 v38; 
  __int64 v39; 
  _QWORD *v40; 
  CHAR Param3; 
  UINT64 v42; 
  _MAP_REGISTER_FILE *MapRegisterFile; 
  VOID *MapRegisterBase; 
  __int64(__fastcall *v45)(_DMA_ADAPTER *, INT64, _MDL *, VOID *, unsigned int, INT64, INT64, CHAR); 
  _MDL *Mdl; 
  VOID *CurrentVa; 

  CurrentVa = a4;
  Mdl = a3;
  v8 = a4;
  v9 = a3;
  MapRegisterFile = 0i64;
  v11 = 0i64;
  RealDmaOperation = (__int64(__fastcall *)(_DMA_ADAPTER *, INT64, _MDL *, VOID *, unsigned int, INT64, INT64, CHAR))ViGetRealDmaOperation((ULONG_PTR)DmaAdapter, 0x58ui64);
  LOBYTE(v13) = 1;
  v45 = RealDmaOperation;
  AdapterInformationInternal = ViGetAdapterInformationInternal(DmaAdapter, v13);
  v15 = Length;
  v16 = (__int64)AdapterInformationInternal;
  if( !AdapterInformationInternal )
    goto LABEL_19;
  VF_ASSERT_IRQL(2u);
  if( !v9 )
    return -1073741811;
  _InterlockedIncrement((volatile signed __int32 *)(v16 + 164));
  _InterlockedIncrement((volatile signed __int32 *)(v16 + 168));
  v9 = Mdl;
  VERIFY_BUFFER_LOCKED(Mdl);
  if( *(_DWORD *)(v16 + 192) == 3 )
  {
    v18 = ViCheckMdlLength(v9, 0i64, v15);
    if( v18 )
    {
      v19 = v18;
      ViHalPreprocessOptions(
        &unk_140C12D10,
        (PSTR)"The provided MDL is not sufficient to satisfy the requested length",
        0x24ui64,
        v18,
        0i64,
        0i64,
        v42);
      VfReportIssueWithOptions(0xE6ui64, 0x24u, v19, 0, 0, &unk_140C12D10);
    }
  }
  v20 = ExAllocateFromNPagedLookasideList(&ViHalWaitBlockLookaside);
  v8 = CurrentVa;
  v11 = v20;
  if( v20 )
  {
    v20[8] = 0i64;
    v21 = a7;
    *v20 = a7;
    ByteOffset = (unsigned __int16)v8 & 0xFFF;
    v23 = a6;
    v24 = v9;
    v11[10] = v11 + 9;
    v11[9] = v11 + 9;
    v11[1] = v23;
    v25 = LODWORD(v9->StartVa) + v9->ByteOffset + v9->ByteCount - (_DWORD)v8;
    ByteCount = v25;
    v27 = 0;
    while( v25 < v15 )
    {
      v24 = v24->Next;
      if( !v24 )
        break;
      v28 = ByteOffset + 4095;
      ByteOffset = v24->ByteOffset;
      v29 = ByteCount + v28;
      ByteCount = v24->ByteCount;
      v27 += v29 >> 12;
      v25 += ByteCount;
    }
    if( v25 + 4096 < ByteOffset + v15 )
    {
      DECREMENT_SCATTER_GATHER_LISTS(v16);
      ExFreeToNPagedLookasideList(&ViHalWaitBlockLookaside, v11);
      return -1073741789;
    }
    v11[7] = v16;
    v30 = v27 + ((ByteOffset + ByteCount - v25 + v15 + 4095) >> 12);
    *((_DWORD *)v11 + 12) = v30;
    v31 = ViAllocateMapRegisterFile((_ADAPTER_INFORMATION *)v16, v30);
    MapRegisterBase = v31;
    v32 = v31;
    if( v31 )
    {
      *((_BYTE *)v31 + 25) = 1;
      v11[12] = v31;
      v11[2] = v11 + 13;
      Param3 = WriteToDevice;
      v11[3] = v8;
      *((_DWORD *)v11 + 8) = v15;
      if( (unsigned int)ViMapDoubleBuffer(v31, v9, v8, v15, Param3) )
      {
        v33 = (_OWORD *)v11[2];
        MapRegisterFile = v32;
        v21 = (INT64)v11;
        *v33 = *(_OWORD *)&v9->Next;
        v33[1] = *(_OWORD *)&v9->Process;
        v33[2] = *(_OWORD *)&v9->StartVa;
        ViSwap(&MapRegisterBase, &Mdl, &CurrentVa);
        v8 = CurrentVa;
        v34 = (INT64)ViScatterGatherCallback;
        v9 = Mdl;
        goto LABEL_21;
      }
      ViFreeMapRegisterFile((_ADAPTER_INFORMATION *)v16, v32);
    }
    ExFreeToNPagedLookasideList(&ViHalWaitBlockLookaside, v11);
    v11 = 0i64;
  }
  else
  {
LABEL_19:
    v21 = a7;
  }
  v34 = a6;
LABEL_21:
  v35 = v45(DmaAdapter, a2, v9, v8, v15, v34, v21, WriteToDevice);
  v36 = v35;
  if( v16 && v35 < 0 )
  {
    DECREMENT_SCATTER_GATHER_LISTS(v16);
    if( MapRegisterFile )
      ViFreeMapRegisterFile((_ADAPTER_INFORMATION *)v16, MapRegisterFile);
    if( v11 )
    {
      v37 = (UINT64 *)(v16 + 72);
      v38 = (unsigned __int8)KeAcquireSpinLockRaiseToDpc((UINT64 *)(v16 + 72));
      v39 = v11[9];
      v40 = (_QWORD *)v11[10];
      if( *(_QWORD **)(v39 + 8) != v11 + 9 || (_QWORD *)*v40 != v11 + 9 )
        __fastfail(3u);
      *v40 = v39;
      *(_QWORD *)(v39 + 8) = v40;
      KxReleaseSpinLock(v37);
      __writecr8(v38);
      ExFreeToNPagedLookasideList(&ViHalWaitBlockLookaside, v11);
    }
  }
  return v36;
}

Referenced by:

No references.