阅读:1915回复:13
大家来拍砖.我在sfilter中实现的取全路径名.应该是没问题了
如果FileObject.Buffer只是a.txt这种.暂时处理是在设备路径后加上0x5C
过滤了查询磁盘信息的FileObject 目前用在查毒引擎的MJ_CREATE中. 希望大牛能指点指点.不胜荣幸. NTSTATUS GetFullPathName (IN PFILE_OBJECT fileObject, OUT PUNICODE_STRING fullPathName ) { #define BUFFER_SIZE 256 NTSTATUS status; ULONG size; ANSI_STRING dbgString; POBJECT_NAME_INFORMATION nameInfo; RtlZeroMemory(fullPathName->Buffer ,MAX_PATH * 2); //如果无文件路径,返回成功.跳出认证 if(!fileObject->FileName.Buffer) { DbgPrint("SKIP a emty dir."); return STATUS_SUCCESS; } //如果两个缓冲区的分配操作其中失败一个 if (!(nameInfo = ExAllocatePool( NonPagedPool, BUFFER_SIZE ))) { DbgPrint("Namebuffer fail!"); return STATUS_BUFFER_FAIL; } //检测文件对象的长度. if (fileObject->FileName.Length) { status = ObQueryNameString( fileObject, nameInfo, BUFFER_SIZE, &size ); } //长度为零,代表这是一次磁盘信息的操作.或者整卷操作 //我们跳过 else { status = STATUS_SUCCESS; goto routieReturn; } //成功获取了卷设备名 if (NT_SUCCESS( status )) { RtlCopyUnicodeString(fullPathName ,&nameInfo->Name); status = RtlAppendUnicodeStringToString(fullPathName ,&fileObject->FileName); // 调试信息路径,ANSI字符缓冲区分配 dbgString.MaximumLength = MAX_PATH; dbgString.Buffer = ExAllocatePool(NonPagedPool, MAX_PATH); //如果分配成功,显示信息 if(dbgString.Buffer) { RtlUnicodeStringToAnsiString(&dbgString,fullPathName,TRUE); DbgPrint("Size:%dByte,The file is:%s",dbgString.Length ,dbgString.Buffer); ExFreePool(dbgString.Buffer); } else { DbgPrint("Allocate a ANSI string memory fail!"); } //不管ANSI缓冲区分配结果.都要返回UNICODE_STRING缓冲区和其长度. goto routieReturn; } //获取卷设备名失败了 else { goto routieReturn; } routieReturn: ExFreePool( nameInfo ); return status; } |
|
最新喜欢:![]() |
沙发#
发布于:2007-02-20 16:58
可能是你的if执行的结构不是你期望的?
|
|
板凳#
发布于:2007-02-14 16:55
to:liio我把我的SfCreate给你看看,帮忙看看错在哪里?谢谢
NTSTATUS SfCreate ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++ Routine Description: This function filters create/open operations. It simply establishes an I/O completion routine to be invoked if the operation was successful. Arguments: DeviceObject - Pointer to the target device object of the create/open. Irp - Pointer to the I/O Request Packet that represents the operation. Return Value: The function value is the status of the call to the file system's entry point. --*/ { NTSTATUS status; UNICODE_STRING fullPathName; //WCHAR nameBuffer[512]; PIO_STACK_LOCATION irpSp; irpSp = IoGetCurrentIrpStackLocation( Irp ); PAGED_CODE(); // // If this is for our control device object, don't allow it to be opened. // //KdPrint(("SfCreate:A \n")); if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject)) { // // Sfilter doesn't allow for any communication through its control // device object, therefore it fails all requests to open a handle // to its control device object. // // See the FileSpy sample for an example of how to allow creates to // the filter's control device object and manage communication via // that handle. // Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; Irp->IoStatus.Information = 0; KdPrint(("SfCreate:FFA \n")); IoCompleteRequest( Irp, IO_NO_INCREMENT ); return STATUS_INVALID_DEVICE_REQUEST; } //KdPrint(("SfCreate:B \n")); ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject )); //KdPrint(("SfCreate:C \n")); // // If debugging is enabled, do the processing required to see the packet // upon its completion. Otherwise, let the request go with no further // processing. // //GetFullPathName(irpSp->FileObject,&fullPathName); if (!FlagOn( SfDebug, SFDEBUG_DO_CREATE_COMPLETION | SFDEBUG_GET_CREATE_NAMES| SFDEBUG_DISPLAY_CREATE_NAMES )) { // // Don't put us on the stack then call the next driver // GetFullPathName(irpSp->FileObject,&fullPathName); IoSkipCurrentIrpStackLocation( Irp ); //KdPrint(("SfCreate:C \n")); KdPrint(("It is be excuted\n")); //GetFullPathName(irpSp->FileObject,&fullPathName); return IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp ); } else { KEVENT waitEvent; KdPrint(("SfCreate:D \n")); // // Initialize an event to wait for the completion routine to occur // KeInitializeEvent( &waitEvent, NotificationEvent, FALSE ); // // Copy the stack and set our Completion routine // IoCopyCurrentIrpStackLocationToNext( Irp ); IoSetCompletionRoutine( Irp, SfCreateCompletion, &waitEvent, TRUE, TRUE, TRUE ); // // Call the next driver in the stack. // status = IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp ); // // Wait for the completion routine to be called // if (STATUS_PENDING == status) { NTSTATUS localStatus = KeWaitForSingleObject(&waitEvent, Executive, KernelMode, FALSE, NULL); ASSERT(STATUS_SUCCESS == localStatus); } // // Verify the IoCompleteRequest was called // ASSERT(KeReadStateEvent(&waitEvent) || !NT_SUCCESS(Irp->IoStatus.Status)); // // Retrieve and display the filename if requested // if (FlagOn(SfDebug, (SFDEBUG_GET_CREATE_NAMES|SFDEBUG_DISPLAY_CREATE_NAMES))) { SfDisplayCreateFileName( Irp ); } //KdPrint(("It is be excuted\n")); //GetFullPathName(irpSp->FileObject,&fullPathName); // // Save the status and continue processing the IRP // status = Irp->IoStatus.Status; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return status; } } |
|
地板#
发布于:2007-02-14 09:45
驱动应该是运行了,我通过debugview的输出信息,确定驱动已经进入了SfCreate函数当中
|
|
地下室#
发布于:2007-02-13 15:49
abayo:
检查驱动是否运行。 michaelgz: 我英文不太好,不能用e文回你 每次你都来看我帖子。谢谢。你说的问题是对的。我也意识到。这个routie只能在MJ_CREATE其他地方需要另外处理 |
|
5楼#
发布于:2007-02-13 00:54
引用第0楼liio于2007-02-11 11:03发表的“大家来拍砖.我在sfilter中实现的取全路径名.应该是没问题了”: I think your function can only be used in MJ_CREATE completion routine, not in dispatch routine before MJ_CREATE IRP is sent down to FSD. In MJ_CREATE dispatch routine, the file object is not fully constructed yet, it should not be used for query. Also in dispatch routine, FileObject.RelatedFileObject field must be checked for relative CREATE request. |
|
6楼#
发布于:2007-02-12 21:27
看一下调试的参数设置
|
|
7楼#
发布于:2007-02-12 17:40
liio你好,我按照你的代码,在sfilter的SfCreate调用你的函数,然后安装驱动程序,重启后再用dbgview观察
获取打开文件的全路径,发现甚么也没有,请问这是甚么原因,初学写驱动,请多多指教 |
|
驱动小牛
![]() |
8楼#
发布于:2007-02-12 14:24
filespy有取全路径的原代码
|
|
9楼#
发布于:2007-02-12 12:34
RtlUnicodeStringToAnsiString(&dbgString,fullPathName,TRUE);
是否应该为 RtlUnicodeStringToAnsiString(&dbgString,fullPathName,FALSE); 为TRUE时,应该是自动分配内存吧. |
|
10楼#
发布于:2007-02-11 17:00
ANSI_STRING dbgString;这一句是为了把中文显示出来.或者你需要跟用户模式通讯的话也可以使用这个.
我纯粹是为了调试.所以没有考虑过多的. 关于上一楼说的0x5c的处理.也可以用RtlAppendXXX来添加.我之所以手动. 是因为那个函数好象有点处理不正确. |
|
11楼#
发布于:2007-02-11 16:57
我也是抛砖引玉.只有拿出自己的代码大家一起讨论,才有进步的.
相互学习嘛. //处理不是以/开头的文件名,避免0x34错误. if(fileObject->FileName.Buffer[0] != 0x5C) { devLen = wcslen(nameInfo->Name.Buffer); fullPathName->Buffer[devLen] = 0x5C; fullPathName->Buffer[devLen + 1] = 0x00; fullPathName->Length += 2; } 这段需要加到RtlCopyUnicodeString(fullPathName ,&nameInfo->Name);后面 是用来处理不是以0x5c开头的FileObject.Filename的 我只是简单的加了0x5c,大家可以根据需要设置为环境变量里的路径. 加0x5c仍然会是路径找不到的 之所以处理是因为系统启动时会产生许多的不带路径的文件请求. 如:advapi.dll之类的,如果需要检测这些加载请处理这部分. 代码写得不好.见笑了 |
|
12楼#
发布于:2007-02-11 16:18
感谢liio的帮忙,我现在去试一试
|
|
13楼#
发布于:2007-02-11 13:49
嗯.尝试一下.
|
|
|