当前位置:编程学习 > 网站相关 >>

文件监控(教学版)

参考FileSpy写的文件监控程序,但比它的抽象多了。可能瑞星的文件驱动也是这样写的,否则它为什么老阻止我安装驱动呢。测试程序是一个命令行小程序,负责打开设备,开启监控和关闭监控,运行时开启和关闭两次。
 
在DebugView中查看输出信息,我只是想看看能不能达到目的,所以信息量很少。
 
在驱动程序中开启和关闭监控的代码:
 
VOID AttachedToDeviceByName (__in PWSTR DeviceName, __in BOOLEAN attach)
{
  UCHAR tmp_buf1[50];
  UNICODE_STRING volumeName;
  NTSTATUS status;
  OBJECT_ATTRIBUTES objectAttributes;
  IO_STATUS_BLOCK openStatus;
  HANDLE fileHandle;
  PDEVICE_OBJECT volume_obj, fs_obj, spy_obj;
  PFILESPY_DEVICE_EXTENSION devExt;
  ULONG i;
  LARGE_INTEGER interval;
  PDEVICE_OBJECT current_obj, next_obj;
  PAGED_CODE();
 
  //应用程序传过来的盘符
  RtlInitEmptyUnicodeString(&volumeName, (PWSTR)tmp_buf1, sizeof(tmp_buf1));
  RtlAppendUnicodeToString(&volumeName, L"\\DosDevices\\");
  status = RtlAppendUnicodeToString(&volumeName, DeviceName);
 
  InitializeObjectAttributes( &objectAttributes,
                &volumeName,
                OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                NULL,
                NULL );
  status = ZwCreateFile( &fileHandle,
               SYNCHRONIZE|FILE_READ_DATA,
               &objectAttributes,
               &openStatus,
               NULL,
               0,
               FILE_SHARE_READ|FILE_SHARE_WRITE,
               FILE_OPEN,
               FILE_SYNCHRONOUS_IO_NONALERT,
               NULL,
               0 );
  status = ObReferenceObjectByHandle( fileHandle,
                    FILE_READ_DATA,
                    *IoFileObjectType,
                    KernelMode,
                    &volume_obj,
                    NULL );
  fs_obj = IoGetBaseFileSystemDeviceObject( volume_obj );
  ObReferenceObject( fs_obj );
 
  if(attach)
  {    
    ObDereferenceObject( volume_obj );
    ZwClose( fileHandle );
 
    status = IoCreateDevice( gFileSpyDriverObject,
                sizeof( FILESPY_DEVICE_EXTENSION ),
                NULL,
                fs_obj->DeviceType,
                0,
                FALSE,
                &spy_obj );
 
    devExt = spy_obj->DeviceExtension;
    devExt->AttachedToDeviceObject = NULL;
 
    ASSERT( IS_FILESPY_DEVICE_OBJECT( spy_obj ) );
 
    SetFlag( spy_obj->Flags, FlagOn( fs_obj->Flags, (DO_BUFFERED_IO | DO_DIRECT_IO | DO_SUPPORTS_TRANSACTIONS)));
    SetFlag( spy_obj->Characteristics, FlagOn( fs_obj->Characteristics, (FILE_DEVICE_SECURE_OPEN) ));
 
    for (i=0; i < 8; i++)
    {
      status = IoAttachDeviceToDeviceStackSafe( spy_obj, fs_obj, &devExt->AttachedToDeviceObject );
      if (NT_SUCCESS(status) )
      {
        break;
      }
      interval.QuadPart = (500 * DELAY_ONE_MILLISECOND);
      KeDelayExecutionThread( KernelMode, FALSE, &interval );
    }
 
    ClearFlag(spy_obj->Flags, DO_DEVICE_INITIALIZING);
    ObDereferenceObject( fs_obj );
  }
  else
  {
    current_obj = IoGetAttachedDeviceReference( fs_obj );
 
    while (NULL != current_obj)
    {
      if (IS_FILESPY_DEVICE_OBJECT( current_obj ))
      {
        spy_obj = current_obj;
        break;
      }
      next_obj = IoGetLowerDeviceObject( current_obj );
      ObDereferenceObject( current_obj );
      current_obj = next_obj;
    }
 
    ObDereferenceObject( volume_obj );
    ZwClose( fileHandle );
 
    devExt = spy_obj->DeviceExtension;
    IoDetachDevice( devExt->AttachedToDeviceObject );
 
    IoDeleteDevice( spy_obj );
    ObDereferenceObject( spy_obj );
    ObDereferenceObject( spy_obj );
    ObDereferenceObject( spy_obj );
 
    interval.QuadPart = (5 * DELAY_ONE_SECOND); //等5秒
    KeDelayExecutionThread( KernelMode, FALSE, &interval );
    ObDereferenceObject( fs_obj );
  }  
}
写的时候遇到一个有趣的问题是,驱动安装卸载一次,然后再安装,应用程序就不能访问它了,GetError()提示说系统找不到指定的文件。原来是卸载的时候没有卸干净,所以第二次不能用,程序中有相连的三句话“ObDereferenceObject( spy_obj);”正是我担心spy_obj不释放才出此下策。
补充:综合编程 , 其他综合 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,