reborn
驱动小牛
驱动小牛
  • 注册日期2006-07-21
  • 最后登录2007-10-13
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望144点
  • 贡献值0点
  • 好评度143点
  • 原创分0分
  • 专家分0分
阅读:1339回复:1

想在SFCREATE里获得文件名,按照FILEMON搬来的,贴段代码,大家看看有没有问题?

楼主#
更多 发布于:2007-01-04 15:20
  VOID
SfGetFullPath(
              PFILE_OBJECT FileObject,
              PSFILTER_DEVICE_EXTENSION DevExt,
              PCHAR fullPathName
              )
{
    PHASH_ENTRY  hashEntry, newEntry;
    ULONG        pathLen, prefixLen, slashes;
    PFILE_OBJECT     relatedFileObject;
    ANSI_STRING      fileName;
    ANSI_STRING      relatedName;
    PCHAR       pathOffset, ptr;
    
    if(fullPathName)
    {
        fullPathName[0] = 0;
    }
    
    KeEnterCriticalRegion();
    ExAcquireResourceSharedLite(&HashResource, TRUE);
    
    hashEntry = HashTable[HASHOBJECT( FileObject )];
    while(hashEntry && hashEntry->FileObject != FileObject)
    {
        hashEntry = hashEntry->Next;
    }
    //
    // Did we find an entry?
    //
    if( hashEntry )
    {
        //
        // Yes, so get the name from the entry.
        //
        strcpy( fullPathName, hashEntry->FullPathName );
        ExReleaseResourceLite( &HashResource );
        KeLeaveCriticalRegion();
        return;
    }
    
    ExReleaseResourceLite( &HashResource );
    KeLeaveCriticalRegion();

    if( !FileObject || FileObject->DeviceObject->DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM )
    {
        prefixLen = 0;
    }
    else
    {
        prefixLen = 2; // "C:"
    }
    if( !FileObject )
    {
        sprintf(fullPathName, "%C:", DevExt->DriveLetter);
        return;
    }
    // Initialize variables
    //
    fileName.Buffer = NULL;
    relatedName.Buffer = NULL;
    if(!FileObject->FileName.Buffer)
    {
        sprintf(fullPathName, "%C:", DevExt->DriveLetter);
        return;
    }
    if( !NT_SUCCESS( RtlUnicodeStringToAnsiString( &fileName, &FileObject->FileName, TRUE )))
    {
        sprintf( fullPathName, "%C: <Out of Memory>", DevExt->DriveLetter);
        return;
    }

    pathLen = fileName.Length + prefixLen;
    relatedFileObject = FileObject->RelatedFileObject;

    if( FileObject->FileName.Buffer[0] != L'\\' && relatedFileObject && relatedFileObject->FileName.Length )
    {
        if( !NT_SUCCESS( RtlUnicodeStringToAnsiString( &relatedName, &relatedFileObject->FileName, TRUE )))
        {
            sprintf( fullPathName, "%C: <Out of Memory>", DevExt->DriveLetter);
            RtlFreeAnsiString( &fileName );
            return;
        }
        pathLen += relatedName.Length+1;
    }
    
    // Add the drive letter first at the front of the name
    //
    if( FileObject->DeviceObject->DeviceType != FILE_DEVICE_NETWORK_FILE_SYSTEM )
    {
        sprintf( fullPathName, "%C:", DevExt->DriveLetter );
    }
    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 );
            }
        }
    }  
    if( fileName.Buffer ) RtlFreeAnsiString( &fileName );
    if( relatedName.Buffer ) RtlFreeAnsiString( &relatedName );
    //
    // Network redirector names already specify a share name that we
    // have to strip:
    //
    //     \X:\computer\share\realpath
    //
    // And we want to present:
    //
    //     X:\realpath
    //
    // to the user.
    //
    if( FileObject->DeviceObject->DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM &&
        strlen( fullPathName ) >= strlen("\\X:\\") )
    {
        
        //
        // If this is Win2k the name is specified like this:
        //
        //    \;X:0\computer\share\realpath
        //
        // so we have to handle that case as well
        //
        if( fullPathName[1] == ';' )
        {
            
            //
            // Win2K-style name. Grab the drive letter
            // and skip over the share
            //
            fullPathName[0] = fullPathName[2];
            fullPathName[1] = ':';
            fullPathName[2] = '\\';
            
            //
            // The third slash after the drive is the
            // start of the real path (we start scanning
            // at the ':' since we don't want to make assumptions
            // about the length of the number).
            //
            slashes = 0;
            ptr = &fullPathName[3];
            while( *ptr && slashes != 3 )
            {
                if( *ptr == '\\' ) slashes++;
                ptr++;
            }
            strcpy( &fullPathName[3], ptr );
            
        }
        else if( fullPathName[2] == ':' )
        {
            
            //
            // NT 4-style name. Skip the share name
            //
            fullPathName[0] = fullPathName[1];
            fullPathName[1] = ':';
            fullPathName[2] = '\\';
            
            //
            // The second slash after the drive's slash (x:\)
            // is the start of the real path
            //
            slashes = 0;
            ptr = &fullPathName[3];
            while( *ptr && slashes != 3 )
            {
                if( *ptr == '\\' ) slashes++;
                ptr++;
            }
            strcpy( &fullPathName[3], ptr );
            
        }
        else
        {  
            //
            // Its a UNC path, so add a leading slash
            //
            RtlMoveMemory( &fullPathName[1], fullPathName, strlen( fullPathName ) + 1);
            fullPathName[0] = '\\';
        }
    }
    // Allocate a hash entry
    //
    newEntry = ExAllocatePool( NonPagedPool, sizeof(HASH_ENTRY ) + strlen( fullPathName ) + 1);
    //
    // If no memory for a new entry, oh well.
    //
    if( newEntry )
    {
        //
        // Fill in the new entry
        //
        newEntry->FileObject = FileObject;
        strcpy( newEntry->FullPathName, fullPathName );
        
        //
        // Put it in the hash table
        //
        KeEnterCriticalRegion();
        ExAcquireResourceExclusiveLite( &HashResource, TRUE );
        
        newEntry->Next = HashTable[ HASHOBJECT(FileObject) ];
        HashTable[ HASHOBJECT(FileObject) ] = newEntry;    
        
        ExReleaseResourceLite( &HashResource );
        KeLeaveCriticalRegion();
    }

}
请指教
reborn
驱动小牛
驱动小牛
  • 注册日期2006-07-21
  • 最后登录2007-10-13
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望144点
  • 贡献值0点
  • 好评度143点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-01-04 15:23
我只是想在IRP_mj_create里获得文件名,所以把CREATEPATH BOOL去掉了,还有没有用
FilemonQueryFile这个函数
游客

返回顶部