FsRtlAcquireFileForModWriteEx

NTSTATUS __stdcall FsRtlAcquireFileForModWriteEx(
        _FILE_OBJECT *FileObject,
        _LARGE_INTEGER *EndingOffset,
        _ERESOURCE **ResourceToRelease){
  unsigned int v4; 
  char v5; 
  _DEVICE_OBJECT *v6; 
  _DEVICE_OBJECT *v7; 
  _DEVICE_OBJECT *v8; 
  INT64 v9; 
  _DEVICE_OBJECT *v10; 
  _DEVICE_OBJECT *DeviceAttachmentBaseRefWithTag; 
  _DRIVER_OBJECT *DriverObject; 
  _FAST_IO_DISPATCH *FastIoDispatch; 
  _FS_FILTER_CALLBACKS *FsFilterCallbacks; 
  NTSTATUS result; 
  LONGLONG *v16; 
  _ERESOURCE **v17; 
  NTSTATUS v18; 
  char v19; 
  int(__fastcall *AcquireForModWrite)(_FILE_OBJECT *, _LARGE_INTEGER *, _ERESOURCE **, _DEVICE_OBJECT *); 
  _DRIVER_OBJECT *v21; 
  void *FsContext; 
  char v23; 
  LONGLONG v24; 
  _ERESOURCE *v25; 
  char v26; 
  char v27; 
  INT64 v28; 
  char v29; 
  UINT64 v30; 
  UINT8 BaseFsFailedOp[4]; 
  _LARGE_INTEGER *v32; 
  _ERESOURCE **v33; 
  _FS_FILTER_CTRL *v34; 
  _FS_FILTER_CTRL FsFilterCtrl[144]; 

  v33 = ResourceToRelease;
  v32 = EndingOffset;
  memset(FsFilterCtrl, 0i64, 0x238u);
  v4 = 0;
  *(_DWORD *)BaseFsFailedOp = 0;
  v34 = FsFilterCtrl;
  v5 = 0;
  LODWORD(v6) = IoGetRelatedDeviceObject((INT64)FileObject);
  v7 = v6;
  LODWORD(v8) = IoGetBaseFileSystemDeviceObject((INT64)FileObject);
  DeviceAttachmentBaseRefWithTag = v8;
  DriverObject = v8->DriverObject;
  FastIoDispatch = DriverObject->FastIoDispatch;
  FsFilterCallbacks = DriverObject->DriverExtension->FsFilterCallbacks;
  if( FsFilterCallbacks
    && (FsFilterCallbacks->SizeOfFsFilterCallbacks >= 0x50 && FsFilterCallbacks->PreAcquireForModifiedPageWriter
     || FsFilterCallbacks->SizeOfFsFilterCallbacks >= 0x58 && FsFilterCallbacks->PostAcquireForModifiedPageWriter) )
  {
    v5 = 1;
  }
  if( v7 == DeviceAttachmentBaseRefWithTag && !v5 )
  {
    v17 = v33;
    v34 = 0i64;
    v19 = 0;
LABEL_12:
    if( !FsFilterCallbacks
      || (FsFilterCallbacks->SizeOfFsFilterCallbacks < 0x50 || !FsFilterCallbacks->PreAcquireForModifiedPageWriter)
      && (FsFilterCallbacks->SizeOfFsFilterCallbacks < 0x58 || !FsFilterCallbacks->PostAcquireForModifiedPageWriter) )
    {
      if( FastIoDispatch
        && FastIoDispatch->SizeOfFastIoDispatch >= 0x80
        && (AcquireForModWrite = FastIoDispatch->AcquireForModWrite) != 0i64 )
      {
        v4 = AcquireForModWrite(FileObject, v32, v17, DeviceAttachmentBaseRefWithTag);
      }
      else
      {
        v4 = -1073741808;
      }
      *(_DWORD *)BaseFsFailedOp |= 1u;
    }
    if( v19 )
      ObfDereferenceObjectWithTag(DeviceAttachmentBaseRefWithTag, 0x746C6644ui64);
    v16 = (LONGLONG *)v32;
    goto LABEL_25;
  }
  result = FsFilterCtrlInit(FsFilterCtrl, 0xFDu, v7, v10, FileObject, 1u);
  if( result < 0 )
    return result;
  v16 = (LONGLONG *)v32;
  v17 = v33;
  *(_QWORD *)&FsFilterCtrl[6] = v32;
  *(_QWORD *)&FsFilterCtrl[8] = v33;
  v18 = FsFilterPerformCallbacks(FsFilterCtrl, 1u, 1u, BaseFsFailedOp);
  v4 = v18;
  if( v18 >= 0 )
  {
    if( v18 )
    {
      v4 = 0;
      if( v18 != 294 )
        v4 = v18;
      goto LABEL_25;
    }
    FileObject = *(_FILE_OBJECT **)&FsFilterCtrl[4];
    if( (FsFilterCtrl[16] & 4) != 0 )
    {
      DeviceAttachmentBaseRefWithTag = IoGetDeviceAttachmentBaseRefWithTag(
                                         *(_DEVICE_OBJECT **)&FsFilterCtrl[2],
                                         0x746C6644ui64);
      v19 = 1;
      v21 = DeviceAttachmentBaseRefWithTag->DriverObject;
      FastIoDispatch = v21->FastIoDispatch;
      FsFilterCallbacks = v21->DriverExtension->FsFilterCallbacks;
    }
    else
    {
      v19 = 0;
    }
    goto LABEL_12;
  }
LABEL_25:
  if( v4 == -1073741808 && (BaseFsFailedOp[0] & 1) != 0 )
  {
    FsContext = FileObject->FsContext;
    if( *((_QWORD *)FsContext + 1) )
    {
      v23 = *((_BYTE *)FsContext + 4);
      if( (v23 & 8) != 0 || (v24 = *((_QWORD *)FsContext + 5), *v16 > v24) && v24 != *((_QWORD *)FsContext + 4) )
      {
        v26 = 1;
      }
      else
      {
        if( (v23 & 0x10) == 0 )
        {
          v25 = (_ERESOURCE *)*((_QWORD *)FsContext + 2);
          if( v25 )
          {
            v26 = 0;
            goto LABEL_56;
          }
        }
        v26 = 0;
      }
      v25 = (_ERESOURCE *)*((_QWORD *)FsContext + 1);
      while( 1 )
      {
LABEL_56:
        if( v26 )
          v27 = ExAcquireResourceExclusiveLite((UINT64)v25, 0, v9);
        else
          v27 = ExAcquireSharedWaitForExclusive((UINT64)v25, 0, v9);
        if( !v27 )
          goto LABEL_73;
        v29 = *((_BYTE *)FsContext + 4);
        if( (v29 & 8) != 0 || *v16 > *((_QWORD *)FsContext + 5) )
        {
          if( v26 )
            goto LABEL_45;
        }
        else
        {
          if( (v29 & 0x10) == 0 )
          {
            v30 = *((_QWORD *)FsContext + 2);
            if( !v30 || v25 == (_ERESOURCE *)v30 )
            {
              if( v26 )
LABEL_44:
                ExConvertExclusiveToSharedLite(v25);
            }
            else
            {
              v25 = 0i64;
              if( (unsigned __int8)ExAcquireSharedWaitForExclusive(v30, 0, v28) )
                v25 = (_ERESOURCE *)*((_QWORD *)FsContext + 2);
              ExReleaseResourceLite(*((PERESOURCE *)FsContext + 1));
              if( !v25 )
              {
LABEL_73:
                v4 = -1073741608;
                goto LABEL_26;
              }
            }
LABEL_45:
            *v17 = v25;
            goto LABEL_46;
          }
          if( v26 )
            goto LABEL_44;
          if( v25 == *((_ERESOURCE **)FsContext + 1) )
            goto LABEL_45;
        }
        ExReleaseResourceLite(v25);
        v25 = (_ERESOURCE *)*((_QWORD *)FsContext + 1);
        v26 = 1;
      }
    }
    *v17 = 0i64;
LABEL_46:
    v4 = 0;
  }
LABEL_26:
  if( v34 )
  {
    if( *((_WORD *)v34 + 37) )
      FsFilterPerformCompletionCallbacks(FsFilterCtrl, v4);
    if( (FsFilterCtrl[16] & 1) != 0 )
      FsFilterFreeCompletionStack(FsFilterCtrl);
  }
  return v4;
}

Referenced by:

MiGatherMappedPages