IopGraftName

VOID __stdcall IopGraftName(PIRP Irp, _FILE_OBJECT *FileObject, _REPARSE_DATA_BUFFER *ReparseBuffer){
  _FILE_OBJECT *RelatedFileObject; 
  unsigned int v5; 
  VOID **v6; 
  const VOID **v7; 
  NTSTATUS IrpExtraCreateParameter; 
  _RELATIVE_SYMLINK_INFO *v9; 
  __int64 v10; 
  unsigned __int64 v11; 
  char v12; 
  USHORT Reserved; 
  ULONG ReparseTag; 
  bool v15; 
  USHORT SubstituteNameLength; 
  WCHAR *v17; 
  size_t v18; 
  size_t v19; 
  VOID **PoolWithTag; 
  _OBJECT_NAME_INFORMATION *v21; 
  NTSTATUS v22; 
  PVOID v23; 
  VOID **v24; 
  _DWORD *v25; 
  NTSTATUS FileInformation; 
  unsigned int v27; 
  _RELATIVE_SYMLINK_INFO *RelatedMountPoint; 
  UINT16 v29; 
  unsigned int Length; 
  size_t v31; 
  VOID **v32; 
  size_t v33; 
  size_t *v34; 
  char *v35; 
  char *v36; 
  UINT16 RelatedFileNameLength; 
  VOID *v38; 
  unsigned int v39; 
  UINT64 v40; 
  _RELATIVE_SYMLINK_INFO *MostRecentlyUsedName; 
  NTSTATUS updated; 
  int v43; 
  WCHAR *RelatedFileName; 
  VOID *SymlinkInfo; 
  PVOID P; 
  PVOID FileObjecta; 
  UINT64 ReturnLength; 
  struct _ECP_LIST *ExtraCreateParameter; 
  WCHAR *PathBuffer; 
  size_t *v51; 
  _UNICODE_STRING *OpenedName; 
  PVOID v53; 
  char v56; 
  _RELATIVE_SYMLINK_INFO *ToInitialize; 

  RelatedFileObject = FileObject->RelatedFileObject;
  FileObjecta = RelatedFileObject;
  LODWORD(ReturnLength) = 0;
  v5 = 0;
  LOWORD(ToInitialize) = 0;
  v6 = 0i64;
  PathBuffer = 0i64;
  SymlinkInfo = 0i64;
  v7 = 0i64;
  v56 = 0;
  v53 = 0i64;
  P = 0i64;
  v51 = 0i64;
  ExtraCreateParameter = 0i64;
  IrpExtraCreateParameter = IoGetIrpExtraCreateParameter(Irp, &ExtraCreateParameter);
  IopSymlinkGetECP(ExtraCreateParameter, &SymlinkInfo);
  v9 = (_RELATIVE_SYMLINK_INFO *)SymlinkInfo;
  v10 = 4194817i64;
  *((_WORD *)SymlinkInfo + 1) |= 2u;
  if( Irp->IoStatus.Status != 260 )
    IrpExtraCreateParameter = -1073741192;
  v11 = Irp->IoStatus.Information - 2684354563u;
  if( v11 > 0x16 || !_bittest64(&v10, v11) )
    IrpExtraCreateParameter = -1073741192;
  v12 = 0;
  Reserved = ReparseBuffer->Reserved;
  if( !Irp->Tail.AuxiliaryBuffer )
    IrpExtraCreateParameter = -1073741192;
  if( !ReparseBuffer )
    IrpExtraCreateParameter = -1073741192;
  if( Reserved >= 0x4000u )
    IrpExtraCreateParameter = -1073741192;
  ReparseTag = ReparseBuffer->ReparseTag;
  if( ReparseBuffer->ReparseDataLength >= 0x4000u )
    IrpExtraCreateParameter = -1073741192;
  if( ReparseTag + 1610612733 > 0x16 || !_bittest((const int *)&v10, ReparseTag + 1610612733) )
    IrpExtraCreateParameter = -1073741192;
  OpenedName = &FileObject->FileName;
  if( !FileObject->FileName.Length )
    IrpExtraCreateParameter = -1073741192;
  v15 = IrpExtraCreateParameter < 0;
  if( IrpExtraCreateParameter >= 0 )
  {
    if( ReparseTag == -1610612733 )
    {
      SubstituteNameLength = ReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength;
      PathBuffer = (WCHAR *)(&ReparseBuffer->GenericReparseBuffer
                           + ReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameOffset
                           + 8);
      LOWORD(ToInitialize) = SubstituteNameLength;
    }
    else if( ReparseTag == -1610612724 )
    {
      v17 = (WCHAR *)((char *)ReparseBuffer->SymbolicLinkReparseBuffer.PathBuffer
                    + ReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameOffset);
      LOWORD(ToInitialize) = ReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength;
      PathBuffer = v17;
      if( (ReparseBuffer->SymbolicLinkReparseBuffer.Flags & 1) == 0 )
        goto LABEL_51;
      v56 = 1;
      v18 = 256;
      v19 = 256;
      if( RelatedFileObject && !IopGetFileObjectExtension(RelatedFileObject, FoExtTypeSymlink, 0i64) )
      {
        while( 1 )
        {
          PoolWithTag = ExAllocatePoolWithTag(1ui64, v19, 1665560393i64);
          v12 = 0;
          P = PoolWithTag;
          v21 = (_OBJECT_NAME_INFORMATION *)PoolWithTag;
          if( !PoolWithTag )
            break;
          memset(PoolWithTag, 0i64, v19);
          v22 = ObQueryNameStringMode(FileObject->DeviceObject, v21, v19, &ReturnLength, 0);
          v12 = 0;
          IrpExtraCreateParameter = v22;
          if( v22 >= 0 )
            goto LABEL_33;
          if( v22 != -2147483643 )
            goto LABEL_32;
          v19 = ReturnLength;
          if( (unsigned int)ReturnLength >= 0xFFFF )
          {
            IrpExtraCreateParameter = -1073741562;
LABEL_32:
            if( IrpExtraCreateParameter >= 0 )
            {
LABEL_33:
              v23 = FileObjecta;
              v5 = *(_WORD *)v21 + OpenedName->Length - ReparseBuffer->Reserved;
              while( 1 )
              {
                v24 = ExAllocatePoolWithTag(1ui64, v18, 1665560393i64);
                v12 = 0;
                v53 = v24;
                v25 = v24;
                if( !v24 )
                {
                  IrpExtraCreateParameter = -1073741670;
                  goto LABEL_40;
                }
                v51 = (size_t *)v24;
                memset(v24, 0i64, v18);
                FileInformation = IopGetFileInformation(v23, v18, FileNameInformation, v25, &ReturnLength);
                v12 = 0;
                IrpExtraCreateParameter = FileInformation;
                if( FileInformation >= 0 )
                  break;
                if( FileInformation != -2147483643 )
                  goto LABEL_40;
                v18 = *v25 + 8;
                if( v18 >= 0xFFFF )
                {
                  IrpExtraCreateParameter = -1073741562;
LABEL_40:
                  v7 = (const VOID **)P;
                  goto LABEL_49;
                }
                ExFreePoolWithTag(v25, 0);
              }
              v27 = v5 + *v25;
              if( v27 < v5 )
              {
                v5 = -1;
                IrpExtraCreateParameter = -1073741675;
                goto LABEL_40;
              }
              v9 = (_RELATIVE_SYMLINK_INFO *)SymlinkInfo;
              v5 += *v25;
              v7 = (const VOID **)P;
              RelatedFileObject = (_FILE_OBJECT *)FileObjecta;
              if( v27 >= 0xFFFF )
                IrpExtraCreateParameter = -1073741562;
              goto LABEL_51;
            }
            v7 = (const VOID **)v21;
LABEL_49:
            RelatedFileObject = (_FILE_OBJECT *)FileObjecta;
            goto LABEL_50;
          }
          ExFreePoolWithTag(v21, 0);
        }
        IrpExtraCreateParameter = -1073741670;
        v7 = 0i64;
        goto LABEL_49;
      }
      v7 = 0i64;
LABEL_50:
      v9 = (_RELATIVE_SYMLINK_INFO *)SymlinkInfo;
LABEL_51:
      Reserved = ReparseBuffer->Reserved;
    }
    else
    {
      IrpExtraCreateParameter = -1073741194;
    }
    if( IrpExtraCreateParameter < 0 )
      goto LABEL_89;
    RelatedMountPoint = IopSymlinkGetRelatedMountPoint(v9, Reserved);
    if( !RelatedMountPoint )
      RelatedMountPoint = IopSymlinkGetMostRecentlyUsedName(v9);
    Length = RelatedMountPoint->OpenedName.Length;
    if( v56 )
    {
      if( !RelatedFileObject || IopGetFileObjectExtension(RelatedFileObject, FoExtTypeSymlink, 0i64) )
      {
        if( v5 <= Length )
          v5 = Length;
      }
      else
      {
        v5 += Length;
      }
      v5 += 2;
    }
    v31 = v5 + v29 + ReparseBuffer->Reserved + 4;
    if( v31 >= 0xFFFF )
    {
      IrpExtraCreateParameter = -1073741562;
    }
    else
    {
      v32 = ExAllocatePoolWithTag(1ui64, v31, 1665560393i64);
      v12 = 0;
      v6 = v32;
      if( !v32 )
      {
        v29 = (unsigned __int16)ToInitialize;
        IrpExtraCreateParameter = -1073741670;
        goto LABEL_69;
      }
      memset(v32, 0i64, v31);
      v29 = (unsigned __int16)ToInitialize;
    }
    v12 = 0;
LABEL_69:
    v33 = v31 - 2;
    if( IrpExtraCreateParameter < 0 )
      goto LABEL_89;
    if( v56 )
    {
      ToInitialize = 0i64;
      if( FileObjecta && !IopGetFileObjectExtension((_FILE_OBJECT *)FileObjecta, FoExtTypeSymlink, 0i64) )
      {
        memmove(v6, v7[1], *(unsigned __int16 *)v7);
        v34 = v51;
        v35 = (char *)v6 + 2 * ((unsigned __int64)*(unsigned __int16 *)v7 >> 1);
        memmove(v35, v51 + 1, *v51);
        v36 = &v35[2 * ((unsigned __int64)*v34 >> 1)];
        if( *FileObject->FileName.Buffer != 92 && *((_WORD *)v36 - 1) != 92 )
        {
          *(_WORD *)v36 = 92;
          LOWORD(v36) = (_WORD)v36 + 2;
        }
        RelatedFileNameLength = (_WORD)v36 - (_WORD)v6;
        IopSymlinkRemoveECP(ExtraCreateParameter, (_RELATIVE_SYMLINK_INFO **)&SymlinkInfo);
        v38 = SymlinkInfo;
        v39 = *((unsigned __int16 *)SymlinkInfo + 8) + 2 + RelatedFileNameLength;
        if( v39 >= 0xFFFF )
        {
          IrpExtraCreateParameter = -1073741562;
LABEL_78:
          ExFreePoolWithTag(v6, 0);
LABEL_88:
          v12 = 0;
LABEL_89:
          if( v56 != v12 )
          {
            if( P )
              ExFreePoolWithTag(P, 0);
            if( v53 )
              ExFreePoolWithTag(v53, 0);
          }
          goto LABEL_94;
        }
        IrpExtraCreateParameter = IopSymlinkAllocateAndAddECP(Irp, &ToInitialize, v39);
        if( IrpExtraCreateParameter < 0 )
          goto LABEL_78;
        v40 = v39 + 32;
        v9 = ToInitialize;
        IopSymlinkInitializeSymlinkInfo(
          ToInitialize,
          v40,
          *((WCHAR **)v38 + 3),
          *((_WORD *)v38 + 8),
          *(_WORD *)v38,
          (WCHAR *)v6,
          RelatedFileNameLength,
          *(_WORD *)P,
          *((_WORD *)v38 + 1),
          *((_RELATIVE_SYMLINK_INFO **)v38 + 1));
        FsRtlFreeExtraCreateParameter(v38);
      }
      MostRecentlyUsedName = IopSymlinkGetRelatedMountPoint(v9, ReparseBuffer->Reserved);
      if( !MostRecentlyUsedName )
        MostRecentlyUsedName = IopSymlinkGetMostRecentlyUsedName(v9);
      LODWORD(RelatedFileName) = v33;
      updated = IopSymlinkApplyToOpenedName(
                  FileObject,
                  MostRecentlyUsedName,
                  ReparseBuffer,
                  Irp,
                  (PWCHAR)v6,
                  (UINT64)RelatedFileName);
    }
    else
    {
      IopCopyOverNewPath((WCHAR *)v6, PathBuffer, v29, FileObject, ReparseBuffer->Reserved);
      if( ReparseBuffer->ReparseTag == -1610612733 )
      {
        IrpExtraCreateParameter = IopSymlinkRememberJunction(
                                    ReparseBuffer->Reserved,
                                    FileObject,
                                    Irp,
                                    (_UNICODE_STRING *)v9);
LABEL_94:
        v15 = IrpExtraCreateParameter < 0;
        goto LABEL_95;
      }
      updated = IopSymlinkUpdateECP(Irp, v9, 0, OpenedName, 0, v9->Flags & 0xFFFE);
    }
    IrpExtraCreateParameter = updated;
    goto LABEL_88;
  }
LABEL_95:
  v43 = 260;
  if( v15 )
    v43 = IrpExtraCreateParameter;
  Irp->IoStatus.Status = v43;
}

Referenced by:

IopSymlinkProcessReparse