📄 irp_mj_directory.c
字号:
if ( !CompareFileName( DirectoryBuffer->FileName, DirectoryBuffer->FileNameLength, gFileData->NameInfo, nameInfo) )
{
// If we failed to match then we are not interested in this entry so we incrament the loop
NextDirectoryBuffer = DirectoryBuffer;
DirectoryBuffer = ( PFILE_BOTH_DIR_INFORMATION )((PCHAR) DirectoryBuffer + DirectoryBuffer->NextEntryOffset );
continue;
}
#endif
#if FILTER_BY_TIME
DBG_PRINT( DbgOutput, DBG_IRP_MJ_DIRECTORY, (PRINT_TAG_DIRECTORY "CompareFileTme()\n") );
if ( !CompareFileTime( gFileData->TimeMaskSet,
gFileData->TimeMaskType,
DirectoryBuffer->CreationTime,
DirectoryBuffer->LastAccessTime,
DirectoryBuffer->LastWriteTime,
DirectoryBuffer->ChangeTime,
gFileData->CreationTime,
gFileData->LastAccessTime,
gFileData->LastWriteTime,
gFileData->ChangeTime ) )
{
// If we failed to match then we are not interested in this entry so we incrament the loop
NextDirectoryBuffer = DirectoryBuffer;
DirectoryBuffer = ( PFILE_BOTH_DIR_INFORMATION )((PCHAR) DirectoryBuffer + DirectoryBuffer->NextEntryOffset );
continue;
}
#endif
#if FILTER_BY_ATTRIBUTES
DBG_PRINT( DbgOutput, DBG_IRP_MJ_DIRECTORY, (PRINT_TAG_DIRECTORY "CompareFileAttributes()\n") );
if ( !CompareFileAttributes( DirectoryBuffer->FileAttributes, gFileData->FileAttributes, gFileData->AttributesMaskType ) )
{
// If we failed to match then we are not interested in this entry so we incrament the loop
NextDirectoryBuffer = DirectoryBuffer;
DirectoryBuffer = ( PFILE_BOTH_DIR_INFORMATION )((PCHAR) DirectoryBuffer + DirectoryBuffer->NextEntryOffset );
continue;
}
#endif
/* ================================================================================= **
This is a *FIRST* -or- *MIDDLE ENTRY* in the buffer, This check is first since it is more
likely that we are processing the middle of a list then its end or a single entry
* ================================================================================= **/
if ( DirectoryBuffer->NextEntryOffset > 0 )
{
#if DBG
if ( NextDirectoryBuffer == NULL )
{
#if FILTER_BY_NAME
DBG_PRINT( DbgOutput, DBG_IRP_MJ_DIRECTORY, (PRINT_TAG_DIRECTORY "REMOVING FIRST ENTRY - (%wZ)\n", &gFileData->NameInfo.Name ) );
#endif
}
else
{
#if FILTER_BY_NAME
DBG_PRINT( DbgOutput, DBG_IRP_MJ_DIRECTORY, (PRINT_TAG_DIRECTORY "REMOVING MIDDLE ENTRY - (%wZ)\n", &gFileData->NameInfo.Name ) );
#endif
}
#endif
// This is the length from start of the entry we are going to remove to the end of the buffer
ModifiedLength = Data->Iopb->Parameters.DirectoryControl.QueryDirectory.Length - BufferPosition;
// Allocate a temporary buffer to do our patch work in
TemporaryBuffer = ExAllocatePoolWithTag( NonPagedPool,
ModifiedLength,
POOL_TAG_TEMPORARY_BUFFER );
try
{
// Copy the memory from the end of the entry we are going to remove to the end of the buffer
RtlCopyMemory( TemporaryBuffer,
((PBYTE)DirectoryBuffer + DirectoryBuffer->NextEntryOffset),
ModifiedLength );
// Zero out the trailing data after the removed entry because it feels clean
RtlZeroMemory( DirectoryBuffer,
ModifiedLength+DirectoryBuffer->NextEntryOffset);
// Patch our temporary buffer onto the real buffer removing the current entry.
// Since DirectoryBuffer is a relative position we can always patch over it with
// no starting offset. This allows us to patch first, and any other entry other
// then the last all in the same manner.
RtlCopyMemory( DirectoryBuffer,
TemporaryBuffer,
ModifiedLength );
}
except ( EXCEPTION_EXECUTE_HANDLER )
{
Data->IoStatus.Status = GetExceptionCode();
Data->IoStatus.Information = 0;
DBG_PRINT( DbgOutput, DBG_IRP_MJ_DIRECTORY, (PRINT_TAG_DIRECTORY "Failed FILE REMOVAL - IOStatus.Status 0x%x\n",Data->IoStatus.Status) );
}
// Free our patchwork buffer
ExFreePoolWithTag( TemporaryBuffer, POOL_TAG_TEMPORARY_BUFFER );
// DDK : "...for a callback data structure to indicate that it
// has modified the contents of the structure."
FltSetCallbackDataDirty( Data );
}
/* ================================================================================= **
SL_RETURN_SINGLE_ENTRY Flag set with only a single entry in buffer
* ================================================================================= **/
else if ( ( FlagOn ( SL_RETURN_SINGLE_ENTRY, Data->Iopb->OperationFlags ) ) &&
( NextDirectoryBuffer == NULL ) )
{
#if FILTER_BY_NAME
DBG_PRINT( DbgOutput, DBG_IRP_MJ_DIRECTORY, (PRINT_TAG_DIRECTORY "REMOVING SINGLE ENTRY - (%wZ)\n", &gFileData->NameInfo.Name ) );
#endif
/*
Normally you would re issue the irp if you were not returning any files. I belive there
is a differnt way to do this in a minifilter and need to reseatch the subject more.
*/
/*
// Security wipe just makes me feel better
RtlZeroMemory( DirectoryBuffer, sizeof( FILE_BOTH_DIR_INFORMATION ) );
Data->IoStatus.Information = 0;
DirectoryBuffer = NULL;
//
NextDirectoryBuffer = DirectoryBuffer;
Data->IoStatus.Status = STATUS_NO_MORE_FILES; // STATUS_NO_SUCH_FILE;
continue;
*/
}
/* ================================================================================= **
This is the *LAST ENTRY* in the buffer
* ================================================================================= **/
else if ( DirectoryBuffer->NextEntryOffset == 0 )
{
#if FILTER_BY_NAME
DBG_PRINT( DbgOutput, DBG_IRP_MJ_DIRECTORY, (PRINT_TAG_DIRECTORY "REMOVING LAST ENTRY - (%wZ)\n", &gFileData->NameInfo.Name ) );
#endif
// Zero out entry as well just because it feels clean
RtlZeroMemory( DirectoryBuffer,
ModifiedLength+DirectoryBuffer->NextEntryOffset);
// Zero out the NextEntryOffset like this entry never existed
NextDirectoryBuffer->NextEntryOffset = 0;
// DDK : "...for a callback data structure to indicate that it
// has modified the contents of the structure."
FltSetCallbackDataDirty( Data );
}
NextDirectoryBuffer = DirectoryBuffer;
DirectoryBuffer = ( PFILE_BOTH_DIR_INFORMATION )((PCHAR) DirectoryBuffer + DirectoryBuffer->NextEntryOffset );
} while ( DirectoryBuffer != NextDirectoryBuffer );
// Free
FltReleaseFileNameInformation( nameInfo );
return FLT_POSTOP_FINISHED_PROCESSING;
}
/*
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= **
*
*
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= **
*/
FLT_POSTOP_CALLBACK_STATUS
ProcessFileNamesInformation( IN PCFLT_RELATED_OBJECTS FltObjects,
IN OUT PFLT_CALLBACK_DATA Data,
IN OUT PVOID SafeBuffer )
{
UNICODE_STRING MN;
PFILE_NAMES_INFORMATION DirectoryBuffer = NULL;
PFILE_NAMES_INFORMATION NextDirectoryBuffer = NULL;
ULONG ModifiedLength = 0;
PVOID TemporaryBuffer = NULL;
/////////////
//PFLT_FILE_NAME_INFORMATION nameInfo = NULL;
//////////////
/*
// Response to ZwQueryDirectoryFile()
DBG_PRINT( DbgOutput, DBG_IRP_MJ_DIRECTORY, (PRINT_TAG_DIRECTORY "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^^^^FileNamesInformation\n") );
DBG_PRINT( DbgOutput, DBG_IRP_MJ_DIRECTORY, (PRINT_TAG_DIRECTORY "Query Name (%wZ) DirectoryBuffer Size [%d]",Data->Iopb->Parameters.DirectoryControl.QueryDirectory.FileName,
Data->Iopb->Parameters.DirectoryControl.QueryDirectory.Length) );
DBG_PRINT( DbgOutput, DBG_IRP_MJ_DIRECTORY, (PRINT_TAG_DIRECTORY "IOStatus Info %d\n", Data->IoStatus.Information) );
DirectoryBuffer = ( PFILE_NAMES_INFORMATION ) SafeBuffer;
if ( FlagOn ( SL_RETURN_SINGLE_ENTRY, Data->Iopb->OperationFlags ) )
{
// Check to see if this file matches our template
if ( CompareFileName( DirectoryBuffer->FileName, DirectoryBuffer->FileNameLength, gFileData->NameInfo, nameInfo ) )
{
if ( DirectoryBuffer->NextEntryOffset == 0 )
{
// Security wipe just makes me feel better
RtlZeroMemory( DirectoryBuffer, Data->Iopb->Parameters.DirectoryControl.QueryDirectory.Length );
//Data->IoStatus.Information = 0;
//Data->IoStatus.Status = STATUS_NO_SUCH_FILE; //STATUS_UNSUCCESSFUL; // STATUS_NO_MORE_FILES;
//DirectoryBuffer->FileNameLength = 0;
//RtlZeroMemory( DirectoryBuffer->FileName, DirectoryBuffer->FileNameLength);
FltSetCallbackDataDirty( Data );
//FltReissueSynchronousIo( FltObjects->Instance, Data );
}
else
{
DBG_PRINT( DbgOutput, DBG_IRP_MJ_DIRECTORY, (PRINT_TAG_DIRECTORY "***************************** MORE OFFSET\n") );
}
} // End if ( FlagOn ( SL_RETURN_SINGLE_ENTRY, Data->Iopb->OperationFlags ) )
} // End if ( CompareFileName( DirectoryBuffer2, &gFileData->Name ) )
*/
return FLT_POSTOP_FINISHED_PROCESSING;
}
/*
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= **
*
*
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= **
*/
FLT_POSTOP_CALLBACK_STATUS
ProcessFileDirectoryInformation( IN OUT PFLT_CALLBACK_DATA Data )
{
DBG_PRINT( DbgOutput, DBG_IRP_MJ_DIRECTORY, (PRINT_TAG_DIRECTORY "^^^^^^^^FileDirectoryInformation\n") );
return FLT_POSTOP_FINISHED_PROCESSING;
}
/*
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= **
*
*
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= **
*/
FLT_POSTOP_CALLBACK_STATUS
ProcessFileFullDirectoryInformation( IN OUT PFLT_CALLBACK_DATA Data )
{
DBG_PRINT( DbgOutput, DBG_IRP_MJ_DIRECTORY, (PRINT_TAG_DIRECTORY "^^^^^^^^FileFullDirectoryInformation\n") );
return FLT_POSTOP_FINISHED_PROCESSING;
}
/*
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= **
*
*
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= **
*/
FLT_POSTOP_CALLBACK_STATUS
ProcessFileIdBothDirectoryInformation( IN OUT PFLT_CALLBACK_DATA Data )
{
DBG_PRINT( DbgOutput, DBG_IRP_MJ_DIRECTORY, (PRINT_TAG_DIRECTORY "^^^^^^^^FileIdBothDirectoryInformation\n") );
return FLT_POSTOP_FINISHED_PROCESSING;
}
/*
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= **
*
*
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= **
*/
FLT_POSTOP_CALLBACK_STATUS
ProcessFileIdFullDirectoryInformation( IN OUT PFLT_CALLBACK_DATA Data )
{
DBG_PRINT( DbgOutput, DBG_IRP_MJ_DIRECTORY, (PRINT_TAG_DIRECTORY "^^^^^^^^FileIdFullDirectoryInformation\n") );
return FLT_POSTOP_FINISHED_PROCESSING;
}
/*
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= **
*
*
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= **
*/
FLT_POSTOP_CALLBACK_STATUS
ProcessFileObjectIdInformation( IN OUT PFLT_CALLBACK_DATA Data )
{
DBG_PRINT( DbgOutput, DBG_IRP_MJ_DIRECTORY, (PRINT_TAG_DIRECTORY "^^^^^^^^FileObjectIdInformation\n") );
return FLT_POSTOP_FINISHED_PROCESSING;
}
/*
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= **
*
*
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= **
*/
FLT_POSTOP_CALLBACK_STATUS
ProcessFileReparsePointInformation( IN OUT PFLT_CALLBACK_DATA Data )
{
DBG_PRINT( DbgOutput, DBG_IRP_MJ_DIRECTORY, (PRINT_TAG_DIRECTORY "^^^^^^^^FileDReparsePointInformation\n") );
return FLT_POSTOP_FINISHED_PROCESSING;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -