IopSymlinkRememberJunction

NTSTATUS __stdcall IopSymlinkRememberJunction(
        UINT64 UnparsedPart,
        _FILE_OBJECT *FileObject,
        _IRP *Irp,
        _UNICODE_STRING *BaseSymlinkInfo){
  UINT16 v4; 
  int RelatedFileName; 
  _RELATIVE_SYMLINK_INFO *RelatedMountPoint; 
  _RELATIVE_SYMLINK_INFO *v10; 
  _WORD *p_ExposedNamespaceLength; 
  _WORD *v12; 
  __int16 v13; 
  VOID **PoolWithTag; 
  __int64 v16; 
  UINT16 v17; 
  VOID *SymlinkInfo; 
  _UNICODE_STRING NtFileName; 

  v4 = UnparsedPart;
  RelatedFileName = 0;
  RelatedMountPoint = IopSymlinkGetRelatedMountPoint((_RELATIVE_SYMLINK_INFO *)BaseSymlinkInfo, UnparsedPart);
  p_ExposedNamespaceLength = &RelatedMountPoint->ExposedNamespaceLength;
  if( RelatedMountPoint )
  {
    RelatedMountPoint->ExposedNamespaceLength = v4;
    IopSymlinkFreeRelatedMountPointChain(RelatedMountPoint);
  }
  else
  {
    p_ExposedNamespaceLength = IopSymlinkGetMostRecentlyUsedName(v10);
    SymlinkInfo = p_ExposedNamespaceLength;
    p_ExposedNamespaceLength[1] |= v13;
    *p_ExposedNamespaceLength = v4;
    if( v12 == p_ExposedNamespaceLength )
    {
      if( FileObject->RelatedFileObject )
      {
        v16 = (unsigned __int16)(v12[8] + 2);
        *(_QWORD *)&NtFileName.Length = 0i64;
        NtFileName.Buffer = 0i64;
        v17 = 0;
        RelatedFileName = IopGetRelatedFileName(FileObject, &NtFileName, v16, &v17);
        if( RelatedFileName >= 0 )
        {
          RtlAppendUnicodeToString(&NtFileName, (WCHAR *)L"\\");
          RtlAppendUnicodeStringToString(&NtFileName, BaseSymlinkInfo + 1);
          RelatedFileName = IopSymlinkUpdateECP(
                              Irp,
                              BaseSymlinkInfo,
                              v4,
                              &NtFileName,
                              v17,
                              BaseSymlinkInfo->MaximumLength);
          ExFreePoolWithTag(NtFileName.Buffer, 0);
          if( RelatedFileName < 0 )
            return RelatedFileName;
          IopSymlinkGetECP((_ECP_LIST *)Irp->UserBuffer, &SymlinkInfo);
          p_ExposedNamespaceLength = SymlinkInfo;
        }
      }
    }
  }
  PoolWithTag = ExAllocatePoolWithTag(1ui64, FileObject->FileName.Length + 32i64, 1767075657i64);
  *((_QWORD *)p_ExposedNamespaceLength + 1) = PoolWithTag;
  if( !PoolWithTag )
    return -1073741670;
  IopSymlinkInitializeSymlinkInfo(
    (_RELATIVE_SYMLINK_INFO *)PoolWithTag,
    (unsigned int)FileObject->FileName.Length + 32,
    FileObject->FileName.Buffer,
    FileObject->FileName.Length,
    0,
    0i64,
    0,
    0,
    0,
    0i64);
  return RelatedFileName;
}

Referenced by:

IopGraftName
IopSymlinkProcessReparse