IopReplaceSymlinkPath
INT64 __stdcall IopReplaceSymlinkPath(
WCHAR *OutputBuffer,
UINT64 Position,
FILE_OBJECT *FileObject,
REPARSE_DATA_BUFFER *ReparseBuffer,
UINT64 PathStart,
UINT16 CurrentLength,
UINT64 MaxLength){
unsigned int v7;
USHORT SubstituteNameLength;
UINT64 Reserved;
WCHAR *v12;
UINT8 *v13;
unsigned int v14;
UINT8 *v15;
wchar_t *v16;
WCHAR *v17;
UINT16 v18;
UINT8 *v19;
__int64 v20;
INT64 result;
wchar_t *v22;
unsigned __int16 Length;
unsigned __int16 v24;
wchar_t v25;
__int16 v26;
wchar_t *Buffer;
wchar_t v28;
wchar_t v29;
__int64 v30;
USHORT v31;
wchar_t v32;
struct _REPARSE_DATA_BUFFER::$EDE85F431271D6DB35F60DFE09C35EC8::$E4726FB01B43180CB4D608E8FC40A3CF *Src;
v7 = PathStart;
SubstituteNameLength = ReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameLength;
Reserved = ReparseBuffer->Reserved;
v12 = &OutputBuffer[(unsigned int)PathStart];
v31 = SubstituteNameLength;
v13 = (UINT8 *)&OutputBuffer[(unsigned int)Position];
LOWORD(PathStart) = 0;
LOWORD(v14) = 0;
if( (unsigned int)Position < v7 )
return 3221226104i64;
Src = &ReparseBuffer->GenericReparseBuffer + ReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameOffset + 12;
if( *(_WORD *)Src->DataBuffer == 92 )
{
if( wcsnicmp(OutputBuffer, L"\\Device\\Mup", 0xBui64) )
goto LABEL_8;
Length = FileObject->FileName.Length;
v24 = 0;
v32 = *FileObject->FileName.Buffer;
v25 = v32;
v26 = (v32 != 59) + 3;
if( (Length & 0xFFFE) != 0 )
{
do
{
Buffer = FileObject->FileName.Buffer;
v28 = Buffer[v24];
if( v28 == 92 )
{
--v26;
if( v25 != 59 && v26 == 2 )
{
if( (unsigned __int16)(v24 + 1) < (unsigned __int16)(Length >> 1) && Buffer[v24 + 1] != 59 )
v26 = 0;
v25 = v32;
}
if( !v26 )
goto LABEL_36;
}
*(_WORD *)v13 = v28;
++v24;
Length = FileObject->FileName.Length;
v13 += 2;
}
while( v24 < (unsigned __int16)(Length >> 1) );
}
if( !v26 )
{
LABEL_36:
if( v24 < (unsigned __int16)(Length >> 1) )
{
v29 = FileObject->FileName.Buffer[v24];
do
{
*(_WORD *)v13 = v29;
++v24;
v13 += 2;
v29 = FileObject->FileName.Buffer[v24];
}
while( v29 != 92 && v24 < (unsigned __int16)(FileObject->FileName.Length >> 1) );
}
SubstituteNameLength = v31;
v30 = v7 + v24;
v18 = 2 * v24 + CurrentLength;
v12 = &OutputBuffer[v30];
goto LABEL_9;
}
return 3221226104i64;
}
v15 = (UINT8 *)&OutputBuffer[(unsigned int)Position];
v16 = FileObject->FileName.Buffer;
LOWORD(PathStart) = FileObject->FileName.Length - Reserved;
v14 = (unsigned __int16)PathStart;
memmove(v15, (UINT8 *)v16, (unsigned __int16)PathStart);
v17 = (WCHAR *)&v13[2 * ((unsigned __int64)v14 >> 1)];
if( v17 != v12 )
{
do
{
if( *v17 == 92 )
break;
LOWORD(v14) = v14 - 2;
*v17-- = 0;
LOWORD(PathStart) = v14;
}
while( v17 != v12 );
if( v17 < v12 )
return 3221226104i64;
}
v13 = (UINT8 *)(v17 + 1);
LABEL_8:
v18 = CurrentLength;
LABEL_9:
if( SubstituteNameLength )
{
memmove(v13, Src->DataBuffer, SubstituteNameLength);
LOWORD(v14) = v31 + v14;
LOWORD(PathStart) = v14;
v13 += 2 * ((unsigned __int64)SubstituteNameLength >> 1);
}
if( (_WORD)Reserved )
{
v19 = (UINT8 *)FileObject->FileName.Buffer + FileObject->FileName.Length - Reserved;
if( *((_WORD *)v13 - 1) == 92 && *(_WORD *)v19 == 92 )
{
*(_WORD *)v13 = 0;
v13 -= 2;
LOWORD(v14) = v14 - 2;
}
memmove(v13, v19, Reserved);
LOWORD(PathStart) = Reserved + v14;
v13 += 2 * (Reserved >> 1);
}
*(_WORD *)v13 = 0;
v20 = -1i64;
do
++v20;
while( v12[v20] );
LODWORD(result) = FsRtlRemoveDotsFromPath(v12, 2 * v20, (UINT16 *)&PathStart);
if( (int)result >= 0 )
{
v22 = FileObject->FileName.Buffer;
FileObject->FileName.Length = v18 + PathStart;
FileObject->FileName.MaximumLength = MaxLength;
if( OutputBuffer != v22 )
{
if( v22 )
ExFreePoolWithTag(v22, 0);
FileObject->FileName.Buffer = OutputBuffer;
}
return 0i64;
}
return result;
}Referenced by:
IopSymlinkApplyToOpenedName