文件过滤系统驱动开发Filemon学习笔
2007-12-30 21:37:20 来源:WEB开发网在函数:FilemonGetFullPath( _IsCreate, FileObject, hookExt, fullPathName )中实现了获得被操作的文件名字,此函数代码较多,判断条件复杂,理解起来比较麻烦,下面重点讲解。
对函数FilemonGetFullPath的理解关键在于理顺结构,
此函数的功能就是获得文件名字,获得文件名字一般在三种状态下:
一:在打开文件请求中,但在打开文件前。
二:在打开文件请求中,但在打开文件后,通过在本层驱动中设置完成例程。在完成例程中获得。
三:在过滤到读写等操作时。
而在此函数中,它包含了第一种和第三种方法,通过一些烦琐的条件判断,先判断出目前是处于什么状态中,然后根据不同状态采取不同方法。
先分析当在第一种条件下,此函数的处理方法,可以精炼为如下:VOID
FilemonGetFullPath(
BOOLEAN createPath,
PFILE_OBJECT fileObject,
PHOOK_EXTENSION hookExt,
PCHAR fullPathName
)
{
ULONG pathLen, prefixLen, slashes;
PCHAR pathOffset, ptr;
BOOLEAN gotPath;
PFILE_OBJECT relatedFileObject;
ANSI_STRING fileName;
ANSI_STRING relatedName;
UNICODE_STRING fullUniName;
prefixLen = 2; // "C:"
if( !fileObject ) {
sprintf( fullPathName, "%C:", hookExt->LogicalDrive );
return;
}
//
// Initialize variables
//
fileName.Buffer = NULL;
relatedName.Buffer = NULL;
gotPath = FALSE;
if( !fileObject->FileName.Buffer)
{
sprintf( fullPathName, "%C:", hookExt->LogicalDrive);
return;
}else
DbgPrint("fileOjec->FileName:%s",fileObject->FileName);
if( !NT_SUCCESS( RtlUnicodeStringToAnsiString( &fileName, &fileObject->FileName, TRUE ))) {
sprintf( fullPathName, "%C: <Out of Memory>", hookExt->LogicalDrive );
return;
}
pathLen = fileName.Length + prefixLen;
relatedFileObject = fileObject->RelatedFileObject;
//
// Only look at related file object if this is a relative name
//
if( fileObject->FileName.Buffer[0] != L'' &&
relatedFileObject && relatedFileObject->FileName.Length ) {
DbgPrint("relatedFileObject filename : %s",relatedFileObject->FileName);
if( !NT_SUCCESS( RtlUnicodeStringToAnsiString( &relatedName, &relatedFileObject->FileName, TRUE ))) {
sprintf( fullPathName, "%C: <Out of Memory>", hookExt->LogicalDrive );
RtlFreeAnsiString( &fileName );
return;
}
pathLen += relatedName.Length+1;
}
if( fileObject->DeviceObject->DeviceType != FILE_DEVICE_NETWORK_FILE_SYSTEM ) {
sprintf( fullPathName, "%C:", hookExt->LogicalDrive );
}
if( pathLen >= MAXPATHLEN ) {
strcat( fullPathName, " <Name Too Long>" );
} else {
//
// Now we can build the path name
//
fullPathName[ pathLen ] = 0;
pathOffset = fullPathName + pathLen - fileName.Length;
memcpy( pathOffset, fileName.Buffer, fileName.Length + 1 );
if( fileObject->FileName.Buffer[0] != L'' &&
relatedFileObject && relatedFileObject->FileName.Length ) {
//
// Copy the component, adding a slash separator
//
*(pathOffset - 1) = '';
pathOffset -= relatedName.Length + 1;
memcpy( pathOffset, relatedName.Buffer, relatedName.Length );
//
// If we've got to slashes at the front zap one
//
if( pathLen > 3 && fullPathName[2] == '' && fullPathName[3] == '' ) {
strcpy( fullPathName + 2, fullPathName + 3 );
}
}
}
}
更多精彩
赞助商链接