FsFilterPerformCallbacks

NTSTATUS __stdcall FsFilterPerformCallbacks(
        _FS_FILTER_CTRL *FsFilterCtrl,
        UINT8 AllowFilterToFail,
        UINT8 AllowBaseFsToFail,
        UINT8 *BaseFsFailedOp){
  _DEVICE_OBJECT *v4; 
  UINT8 v9; 
  _DEVICE_OBJECT *AttachedTo; 
  __int16 v11; 
  PFS_FILTER_CALLBACK v12; 
  PFS_FILTER_COMPLETION_CALLBACK v13; 
  unsigned __int16 v14; 
  _DEVICE_OBJECT **v15; 
  void **v16; 
  NTSTATUS result; 
  PFS_FILTER_COMPLETION_CALLBACK PostOperationCallback; 
  PFS_FILTER_CALLBACK PreOperationCallback; 

  v4 = (_DEVICE_OBJECT *)*((_QWORD *)FsFilterCtrl + 1);
  PreOperationCallback = 0i64;
  PostOperationCallback = 0i64;
  *(_DWORD *)BaseFsFailedOp = 2;
  if( !v4 )
    return 0;
  while( 1 )
  {
    v9 = *((_BYTE *)FsFilterCtrl + 4);
    AttachedTo = v4->DeviceObjectExtension->AttachedTo;
    *((_QWORD *)FsFilterCtrl + 1) = v4;
    FsFilterGetCallbacks(v9, v4, &PreOperationCallback, &PostOperationCallback);
    v12 = PreOperationCallback;
    v13 = PostOperationCallback;
    if( !PreOperationCallback )
      break;
    if( PostOperationCallback )
      goto LABEL_4;
    v15 = 0i64;
LABEL_7:
    if( !v12 )
      goto LABEL_13;
    if( v15 )
      v16 = (void **)(v15 + 2);
    else
      v16 = 0i64;
    result = v12((_FS_FILTER_CALLBACK_DATA *)FsFilterCtrl, v16);
    if( result < 0 )
    {
      if( !AllowFilterToFail )
      {
        if( !AttachedTo )
          goto LABEL_36;
        goto LABEL_12;
      }
      if( !AttachedTo )
      {
LABEL_36:
        if( !AllowBaseFsToFail )
          KeBugCheckEx(0x22u, (PVOID)result, 0i64, (PVOID)0x38C, 0i64);
        *(_DWORD *)BaseFsFailedOp |= 1u;
      }
      if( !v15 )
        return result;
LABEL_40:
      --*((_WORD *)FsFilterCtrl + 37);
      return result;
    }
    if( result )
    {
      if( !v15 )
        return result;
      goto LABEL_40;
    }
LABEL_12:
    v11 = -1;
LABEL_13:
    if( v4 == *((_DEVICE_OBJECT **)FsFilterCtrl + 1) )
    {
      if( !AttachedTo )
      {
        if( v15 )
          *((_WORD *)FsFilterCtrl + 37) += v11;
      }
      v4 = v4->DeviceObjectExtension->AttachedTo;
    }
    else
    {
      FsFilterCtrl[16] |= 4u;
      v4 = (_DEVICE_OBJECT *)*((_QWORD *)FsFilterCtrl + 1);
    }
LABEL_16:
    if( !v4 )
      return 0;
  }
  if( !PostOperationCallback )
  {
    v4 = v4->DeviceObjectExtension->AttachedTo;
    if( !AttachedTo )
      *(_DWORD *)BaseFsFailedOp &= ~2u;
    goto LABEL_16;
  }
LABEL_4:
  v14 = *((_WORD *)FsFilterCtrl + 37);
  if( v14 < *((_WORD *)FsFilterCtrl + 36) )
  {
    v15 = (_DEVICE_OBJECT **)(*((_QWORD *)FsFilterCtrl + 10) + 32i64 * *((unsigned __int16 *)FsFilterCtrl + 37));
    *((_WORD *)FsFilterCtrl + 37) = v14 + 1;
    if( v15 )
    {
      *v15 = v4;
      v15[1] = (_DEVICE_OBJECT *)*((_QWORD *)FsFilterCtrl + 2);
      v15[2] = 0i64;
      v15[3] = (_DEVICE_OBJECT *)v13;
      goto LABEL_7;
    }
  }
  if( !AllowFilterToFail )
    KeBugCheckEx(0x22u, 0i64, 0i64, 0i64, 0i64);
  return -1073741670;
}

Referenced by:

FsRtlAcquireFileExclusiveCommon
FsRtlAcquireFileForCcFlushEx
FsRtlAcquireFileForModWriteEx
FsRtlQueryOpen
FsRtlReleaseFile
FsRtlReleaseFileForCcFlush
FsRtlReleaseFileForModWrite