IopReplaceSymlinkPath
NTSTATUS __stdcall IopReplaceSymlinkPath(
WCHAR *OutputBuffer,
UINT64 Position,
_FILE_OBJECT *FileObject,
_REPARSE_DATA_BUFFER *ReparseBuffer,
UINT64 PathStart,
UINT16 CurrentLength,
UINT64 MaxLength){
unsigned int v7;
USHORT SubstituteNameLength;
unsigned __int64 Reserved;
WCHAR *v12;
WCHAR *v13;
unsigned int v14;
WCHAR *v15;
wchar_t *v16;
WCHAR *v17;
UINT16 v18;
_WORD *v19;
__int64 v20;
NTSTATUS result;
wchar_t *v22;
unsigned __int16 Length;
unsigned __int16 v24;
wchar_t v25;
__int16 v26;
wchar_t *Buffer;
WCHAR 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 = &OutputBuffer[(unsigned int)Position];
LOWORD(PathStart) = 0;
LOWORD(v14) = 0;
if( (unsigned int)Position < v7 )
return -1073741192;
Src = &ReparseBuffer->GenericReparseBuffer + ReparseBuffer->SymbolicLinkReparseBuffer.SubstituteNameOffset + 12;
if( *(_WORD *)Src->DataBuffer == 92 )
{
if( wcsnicmp(OutputBuffer, L"\\Device\\Mup", 0xBu) )
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;
}
*v13 = v28;
++v24;
Length = FileObject->FileName.Length;
++v13;
}
while( v24 < (unsigned __int16)(Length >> 1) );
}
if( !v26 )
{
LABEL_36:
if( v24 < (unsigned __int16)(Length >> 1) )
{
v29 = FileObject->FileName.Buffer[v24];
do
{
*v13 = v29;
++v24;
++v13;
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 -1073741192;
}
v15 = &OutputBuffer[(unsigned int)Position];
v16 = FileObject->FileName.Buffer;
LOWORD(PathStart) = FileObject->FileName.Length - Reserved;
v14 = (unsigned __int16)PathStart;
memmove(v15, v16, (unsigned __int16)PathStart);
v17 = &v13[(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 -1073741192;
}
v13 = v17 + 1;
LABEL_8:
v18 = CurrentLength;
LABEL_9:
if( SubstituteNameLength )
{
memmove(v13, Src, SubstituteNameLength);
LOWORD(v14) = v31 + v14;
LOWORD(PathStart) = v14;
v13 += (unsigned __int64)SubstituteNameLength >> 1;
}
if( (_WORD)Reserved )
{
v19 = (wchar_t *)((char *)FileObject->FileName.Buffer + FileObject->FileName.Length - Reserved);
if( *(v13 - 1) == 92 && *v19 == 92 )
{
*v13-- = 0;
LOWORD(v14) = v14 - 2;
}
memmove(v13, v19, Reserved);
LOWORD(PathStart) = Reserved + v14;
v13 += Reserved >> 1;
}
*v13 = 0;
v20 = -1i64;
do
++v20;
while( v12[v20] );
result = FsRtlRemoveDotsFromPath(v12, 2 * v20, (UINT16 *)&PathStart);
if( 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 0;
}
return result;
}Referenced by:
IopSymlinkApplyToOpenedName