IopGraftName

VOID __stdcall IopGraftName(IRP *Irp, FILE_OBJECT *FileObject, REPARSE_DATA_BUFFER *ReparseBuffer){
  struct _DMA_ADAPTER *RelatedFileObject; 
  unsigned int v5; 
  UINT8 *v6; 
  unsigned __int16 *p_Length; 
  int IrpExtraCreateParameter; 
  UNICODE_STRING *v9; 
  __int64 v10; 
  unsigned __int64 v11; 
  char v12; 
  USHORT Reserved; 
  ULONG ReparseTag; 
  bool v15; 
  USHORT SubstituteNameLength; 
  WCHAR *v17; 
  unsigned int v18; 
  unsigned int v19; 
  OBJECT_NAME_INFORMATION *PoolWithTag; 
  OBJECT_NAME_INFORMATION *v21; 
  int v22; 
  FILE_OBJECT *v23; 
  unsigned int *v24; 
  _DWORD *v25; 
  int FileInformation; 
  unsigned int v27; 
  INT64 RelatedMountPoint; 
  UINT16 v29; 
  unsigned int v30; 
  unsigned int v31; 
  UINT8 *v32; 
  unsigned int v33; 
  UINT8 *v34; 
  UINT8 *v35; 
  UINT8 *v36; 
  UINT16 v37; 
  PVOID v38; 
  unsigned int v39; 
  INT16 v40; 
  _RELATIVE_SYMLINK_INFO *MostRecentlyUsedName; 
  int updated; 
  int v43; 
  VOID *Src; 
  PVOID EcpContext; 
  PVOID P; 
  PADAPTER_OBJECT DmaAdapter; 
  UINT64 ReturnLength; 
  struct _ECP_LIST *ExtraCreateParameter; 
  PWCHAR PathBuffer; 
  UINT8 *v51; 
  UNICODE_STRING *p_FileName; 
  PVOID v53; 
  char v56; 
  PVOID v57; 
  RelatedFileObject = (struct _DMA_ADAPTER *)FileObject->RelatedFileObject;
  DmaAdapter = RelatedFileObject;
  LODWORD(ReturnLength) = 0;
  v5 = 0;
  LOWORD(v57) = 0;
  v6 = 0i64;
  PathBuffer = 0i64;
  EcpContext = 0i64;
  p_Length = 0i64;
  v56 = 0;
  v53 = 0i64;
  P = 0i64;
  v51 = 0i64;
  ExtraCreateParameter = 0i64;
  IrpExtraCreateParameter = IoGetIrpExtraCreateParameter(Irp, &ExtraCreateParameter);
  IopSymlinkGetECP(ExtraCreateParameter, (_RELATIVE_SYMLINK_INFO **)&EcpContext);
  v9 = (UNICODE_STRING *)EcpContext;
  v10 = 4194817i64;
  *((_WORD *)EcpContext + 1) |= 2u;
  if( *((_DWORD *)Irp + 12) != 260 )
    IrpExtraCreateParameter = -1073741192;
  v11 = *((_QWORD *)Irp + 7) - 2684354563i64;
  if( v11 > 0x16 || !_bittest64(&v10, v11) )
    IrpExtraCreateParameter = -1073741192;
  v12 = 0;
  Reserved = ReparseBuffer->Reserved;
  if( !*((_QWORD *)Irp + 20) )
    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;
  p_FileName = &FileObject->FileName;
  if( !FileObject->FileName.Length )
    IrpExtraCreateParameter = -1073741192;
  v15 = IrpExtraCreateParameter < 0;
  if( IrpExtraCreateParameter >= 0 )
  {
    if( ReparseTag == -1610612733 )
    {
      SubstituteNameLength = ReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength;
      PathBuffer = (PWCHAR)(&ReparseBuffer->GenericReparseBuffer
                          + ReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameOffset
                          + 8);
      LOWORD(v57) = SubstituteNameLength;
    }
    else if( ReparseTag == -1610612724 )
    {
      v17 = (WCHAR *)((char *)ReparseBuffer->SymbolicLinkReparseBuffer.PathBuffer
                    + ReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameOffset);
      LOWORD(v57) = ReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength;
      PathBuffer = v17;
      if( (ReparseBuffer->SymbolicLinkReparseBuffer.Flags & 1) == 0 )
        goto LABEL_51;
      v56 = 1;
      v18 = 256;
      v19 = 256;
      if( RelatedFileObject && !IopGetFileObjectExtension((_FILE_OBJECT *)RelatedFileObject, FoExtTypeSymlink, 0i64) )
      {
        while( 1 )
        {
          PoolWithTag = (OBJECT_NAME_INFORMATION *)ExAllocatePoolWithTag(PagedPool, v19, 0x63466F49ui64);
          v12 = 0;
          P = PoolWithTag;
          v21 = PoolWithTag;
          if( !PoolWithTag )
            break;
          memset((INT64)PoolWithTag, 0i64);
          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 = (FILE_OBJECT *)DmaAdapter;
              v5 = v21->Name.Length + p_FileName->Length - ReparseBuffer->Reserved;
              while( 1 )
              {
                v24 = (unsigned int *)ExAllocatePoolWithTag(PagedPool, v18, 0x63466F49ui64);
                v12 = 0;
                v53 = v24;
                v25 = v24;
                if( !v24 )
                {
                  IrpExtraCreateParameter = -1073741670;
                  goto LABEL_40;
                }
                v51 = (UINT8 *)v24;
                memset((INT64)v24, 0i64);
                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:
                  p_Length = (unsigned __int16 *)P;
                  goto LABEL_49;
                }
                ExFreePoolWithTag(v25, 0);
              }
              v27 = v5 + *v25;
              if( v27 < v5 )
              {
                v5 = -1;
                IrpExtraCreateParameter = -1073741675;
                goto LABEL_40;
              }
              v9 = (UNICODE_STRING *)EcpContext;
              v5 += *v25;
              p_Length = (unsigned __int16 *)P;
              RelatedFileObject = DmaAdapter;
              if( v27 >= 0xFFFF )
                IrpExtraCreateParameter = -1073741562;
              goto LABEL_51;
            }
            p_Length = &v21->Name.Length;
LABEL_49:
            RelatedFileObject = DmaAdapter;
            goto LABEL_50;
          }
          ExFreePoolWithTag(v21, 0);
        }
        IrpExtraCreateParameter = -1073741670;
        p_Length = 0i64;
        goto LABEL_49;
      }
      p_Length = 0i64;
LABEL_50:
      v9 = (UNICODE_STRING *)EcpContext;
LABEL_51:
      Reserved = ReparseBuffer->Reserved;
    }
    else
    {
      IrpExtraCreateParameter = -1073741194;
    }
    if( IrpExtraCreateParameter < 0 )
      goto LABEL_89;
    RelatedMountPoint = IopSymlinkGetRelatedMountPoint((INT64)v9, Reserved);
    if( !RelatedMountPoint )
      RelatedMountPoint = IopSymlinkGetMostRecentlyUsedName((INT64)v9);
    v30 = *(unsigned __int16 *)(RelatedMountPoint + 16);
    if( v56 )
    {
      if( !RelatedFileObject || IopGetFileObjectExtension((_FILE_OBJECT *)RelatedFileObject, FoExtTypeSymlink, 0i64) )
      {
        if( v5 <= v30 )
          v5 = v30;
      }
      else
      {
        v5 += v30;
      }
      v5 += 2;
    }
    v31 = v5 + v29 + ReparseBuffer->Reserved + 4;
    if( v31 >= 0xFFFF )
    {
      IrpExtraCreateParameter = -1073741562;
    }
    else
    {
      v32 = (UINT8 *)ExAllocatePoolWithTag(PagedPool, v31, 0x63466F49ui64);
      v12 = 0;
      v6 = v32;
      if( !v32 )
      {
        v29 = (unsigned __int16)v57;
        IrpExtraCreateParameter = -1073741670;
        goto LABEL_69;
      }
      memset((INT64)v32, 0i64);
      v29 = (unsigned __int16)v57;
    }
    v12 = 0;
LABEL_69:
    v33 = v31 - 2;
    if( IrpExtraCreateParameter < 0 )
      goto LABEL_89;
    if( v56 )
    {
      v57 = 0i64;
      if( DmaAdapter && !IopGetFileObjectExtension((_FILE_OBJECT *)DmaAdapter, FoExtTypeSymlink, 0i64) )
      {
        memmove(v6, *((UINT8 **)p_Length + 1), *p_Length);
        v34 = v51;
        v35 = &v6[2 * ((unsigned __int64)*p_Length >> 1)];
        memmove(v35, v51 + 4, *(unsigned int *)v51);
        v36 = &v35[2 * ((unsigned __int64)*(unsigned int *)v34 >> 1)];
        if( *FileObject->FileName.Buffer != 92 && *((_WORD *)v36 - 1) != 92 )
        {
          *(_WORD *)v36 = 92;
          LOWORD(v36) = (_WORD)v36 + 2;
        }
        v37 = (_WORD)v36 - (_WORD)v6;
        IopSymlinkRemoveECP(ExtraCreateParameter, (_RELATIVE_SYMLINK_INFO **)&EcpContext);
        v38 = EcpContext;
        v39 = *((unsigned __int16 *)EcpContext + 8) + 2 + v37;
        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, &v57, v39);
        if( IrpExtraCreateParameter < 0 )
          goto LABEL_78;
        v40 = v39 + 32;
        v9 = (UNICODE_STRING *)v57;
        IopSymlinkInitializeSymlinkInfo(
          (INT64)v57,
          v40,
          *((const VOID **)v38 + 3),
          *((_WORD *)v38 + 8),
          *(_WORD *)v38,
          v6,
          v37,
          *(_WORD *)P,
          *((_WORD *)v38 + 1),
          *((_QWORD *)v38 + 1));
        FsRtlFreeExtraCreateParameter(v38);
      }
      MostRecentlyUsedName = (_RELATIVE_SYMLINK_INFO *)IopSymlinkGetRelatedMountPoint(
                                                         (INT64)v9,
                                                         ReparseBuffer->Reserved);
      if( !MostRecentlyUsedName )
        MostRecentlyUsedName = (_RELATIVE_SYMLINK_INFO *)IopSymlinkGetMostRecentlyUsedName((INT64)v9);
      LODWORD(Src) = v33;
      updated = IopSymlinkApplyToOpenedName(
                  FileObject,
                  MostRecentlyUsedName,
                  ReparseBuffer,
                  Irp,
                  (PWCHAR)v6,
                  (UINT64)Src);
    }
    else
    {
      IopCopyOverNewPath((PWCHAR)v6, PathBuffer, v29, FileObject, ReparseBuffer->Reserved);
      if( ReparseBuffer->ReparseTag == -1610612733 )
      {
        IrpExtraCreateParameter = IopSymlinkRememberJunction(ReparseBuffer->Reserved, FileObject, (INT64)Irp, v9);
LABEL_94:
        v15 = IrpExtraCreateParameter < 0;
        goto LABEL_95;
      }
      updated = IopSymlinkUpdateECP(Irp, v9, 0, p_FileName, 0, v9->MaximumLength & 0xFFFE);
    }
    IrpExtraCreateParameter = updated;
    goto LABEL_88;
  }
LABEL_95:
  v43 = 260;
  if( v15 )
    v43 = IrpExtraCreateParameter;
  *((_DWORD *)Irp + 12) = v43;
}

Referenced by:

IopSymlinkProcessReparse