阅读:1373回复:12
devia大侠请教一个问题,多谢!(悬赏50分!!!)
我想在指定的文件夹下禁止新建文件和文件夹的操作,代码如下:
sfcreate() { ...... 完成当前文件夹是否是指定文件夹的判断 CreateDisposition = (irpSp->Parameters.Create.Options>> 24) & 0x000000ff; if(CreateDisposition==FILE_CREATE||CreateDisposition==FILE_OPEN_IF||CreateDisposition==FILE_OVERWRITE_IF) { DbgPrint("==================当前是一个新建文件的操作!!!======================\n"); Irp->IoStatus.Status = STATUS_ACCESS_DENIED; Irp->IoStatus.Information = 0; status = Irp->IoStatus.Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_ACCESS_DENIED; } } 驱动加载后,会出现以下的问题: (1)在指定的文件夹新建文件夹时,系统也提示“无法创建文件夹,拒绝访问”,但是系统还是会新建文件夹,而且新建的文件夹无法访问; (2)在指定的文件夹新建文件时,系统也提示“无法创建文件,文件存在”,但是系统还是会999个新建文件,而且新建的文件无法访问。 看过以前的帖子上也与遇到过来类似的问题,但是没有写是怎么解决的,肯请devia大侠帮忙解答一下! 多谢!!! |
|
最新喜欢:![]() |
沙发#
发布于:2007-05-25 09:14
自己顶起来!
|
|
板凳#
发布于:2007-05-25 14:32
请在SfCreate中尽可能靠近入口的位置写这段代码,
估计你的问题是漏掉了某个IRP而造成的。 |
|
|
地板#
发布于:2007-05-25 14:51
NTSTATUS
SfCreate ( __in PDEVICE_OBJECT DeviceObject, __in PIRP Irp ) { NTSTATUS status; IO_STATUS_BLOCK IoStatus = {0}; PSFILTER_DEVICE_EXTENSION devExt = (PSFILTER_DEVICE_EXTENSION)(DeviceObject->DeviceExtension); PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp ); PAGED_CODE(); // // If this is for our control device object, don't allow it to be opened. // 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_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return STATUS_SUCCESS; } ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject )); #if 1 if( (irpSp->FileObject != NULL) && (irpSp->FileObject->FileName.Buffer != NULL) && (wcsstr(irpSp->FileObject->FileName.Buffer, L"新建") != NULL) ) { // // 失败返回 // Irp->IoStatus.Status = STATUS_ACCESS_DENIED; Irp->IoStatus.Information = 0; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return STATUS_ACCESS_DENIED; } #endif ...... } |
|
|
地下室#
发布于:2007-05-26 11:40
多谢devia大侠,我回去再试试!!!
|
|
5楼#
发布于:2007-05-29 15:08
devia大侠,以下是我的源代码:
NTSTATUS SfCreate (IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp) { NTSTATUS status; KEVENT waitEvent; PUNICODE_STRING name; GET_NAME_CONTROL nameControl; int cmpresult; PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp ); wchar_t* testmyProtectPath = L"\\Device\\HarddiskVolume1\\user\\"; PAGED_CODE(); if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject)) { Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return STATUS_SUCCESS; } ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject )); ///////////////////////////////////////////////////////////////////////////////////////// KeInitializeEvent( &waitEvent, NotificationEvent, FALSE ); IoCopyCurrentIrpStackLocationToNext( Irp ); IoSetCompletionRoutine(Irp,SfCreateCompletion,&waitEvent,TRUE,TRUE,TRUE ); status = IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp ); name = SfGetFileName( irpSp->FileObject, Irp->IoStatus.Status, &nameControl ); cmpresult = wcsncmp(name->Buffer, testmyProtectPath,wcslen(testmyProtectPath)); if(cmpresult == 0) { if( (irpSp->FileObject != NULL) &&(irpSp->FileObject->FileName.Buffer != NULL) &&(wcsstr(irpSp->FileObject->FileName.Buffer, L"新建") != NULL) ) { DbgPrint("==================当前是一个新建文件的操作!!!======================\n"); Irp->IoStatus.Status = STATUS_ACCESS_DENIED; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_ACCESS_DENIED; } } ////////////////////////////////////////////////////////////////////////////////////////// if (STATUS_PENDING == status) { NTSTATUS localStatus = KeWaitForSingleObject(&waitEvent, Executive, KernelMode, FALSE, NULL); ASSERT(STATUS_SUCCESS == localStatus); } ASSERT(KeReadStateEvent(&waitEvent) || !NT_SUCCESS(Irp->IoStatus.Status)); if (FlagOn(SfDebug, (SFDEBUG_GET_CREATE_NAMES|SFDEBUG_DISPLAY_CREATE_NAMES))) { SfDisplayCreateFileName( Irp ); } status = Irp->IoStatus.Status; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return status; } NTSTATUS SfCreateCompletion (IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN PVOID Context) { PKEVENT event = Context; UNREFERENCED_PARAMETER( DeviceObject ); UNREFERENCED_PARAMETER( Irp ); ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject )); KeSetEvent(event, IO_NO_INCREMENT, FALSE); return STATUS_MORE_PROCESSING_REQUIRED; } 我试了你的方法,如果把判断新建文件的操作放在最开始的位置,这样的确可以禁止新建文件,但这样也会禁止整个文件系统都新建文件,而我只是要禁止在user目录下禁止新建文件的操作,所以这里不可避免地要进行获取文件路径的操作,不知道是不是因为获取文件路径会造成IRP的重入?这个问题怎么解决呢? 多谢! |
|
6楼#
发布于:2007-05-29 18:25
Re:devia大侠请教一个问题,多谢!
50分,求解决问题的方法! |
|
7楼#
发布于:2007-05-30 08:38
你可以用WDK中最新的sfilter框架,或者用tooflat的sfilter中方法来获取文件名,
这样可以在你Dispatch到FSD之前来获取文件名; |
|
|
8楼#
发布于:2007-05-30 08:41
你的代码中也有个明显的错误:
如果你IoCallDirver已经成功,那么你只简单的返回STATUS_ACCESS_DENIED是 不行的,所以你还需要Cancel掉先前的打开操作。 |
|
|
9楼#
发布于:2007-05-30 09:10
引用第7楼devia于2007-05-30 08:38发表的 : 其你跟哪里有WDK中最新的sfilter? 谢谢! |
|
10楼#
发布于:2007-05-30 09:16
引用第8楼devia于2007-05-30 08:41发表的 : 我也猜到可能是因为获得文件名的操作引起的,可是不知道怎么处理?因为获取文件名的操作函数是直接用sfilter里的。 devia大侠能具体说说如何Cancel掉先前的打开操作吗? 谢谢! |
|
11楼#
发布于:2007-05-31 14:41
再顶一下!
|
|
12楼#
发布于:2007-06-01 14:50
我的问题怎么没有人回答呀?
大牛救救我吧! |
|