阅读:1747回复:8
请问下能否在IRP_MJ_CREATE的例程中写文件的加密标识?
我的计划是当文件新建的时候就在文件头加上个加密标识,参考了前人的一些文章,使用的函数是IoBuildAsynchronousFsdRequest(.....)。目前在IRP_MJ_CREATE的例程用IoBuildAsynchronousFsdRequest()函数读已有文件中的标识是可以的,但是在文件新建的时候写标识就失败了,我想知道是自己函数处理的问题还是不能用IoBuildAsynchronousFsdRequest(.....)在IRP_MJ_CREATE的例程写标识,先谢谢热心解答的大侠。
|
|
沙发#
发布于:2009-02-25 12:19
自己re一个.......菜鸟的路真崎岖,也许这个问题太幼稚了,高手都没兴趣回答啊。
|
|
板凳#
发布于:2009-02-26 17:04
谢谢大侠的谢心回复。我写加密标识是在文件新建完成后写的,用的函数是自定义的SfWriteEncryptFlag。
这样贴代码有些凌乱,希望大侠不见怪。由于小弟对这个理解不深,可能会有一些常识性的错误。 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; // //添加部分 // PSFILTER_DEVICE_EXTENSION DevExt = (PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension; PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); PFILE_OBJECT FileObject = IrpSp->FileObject; PWSTR FileName = NULL; ULONG FileNameLength = 0; NTSTATUS Status = STATUS_SUCCESS; POST_CREATE_WORKER_CONTEXT WorkerCtx; // UNICODE_STRING UNIFileName; // ANSI_STRING ANSIFileName; // WCHAR UNIBuf[MAX_PATH]; // CHAR ANSIBuf[MAX_PATH]; 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_INVALID_DEVICE_REQUEST; Irp->IoStatus.Information = 0; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return STATUS_INVALID_DEVICE_REQUEST; } ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject )); // // If debugging is enabled, do the processing required to see the packet // upon its completion. Otherwise, let the request go with no further // processing. // // // We only care about volume filter device object // 我们仅关心卷过滤设备对象 // if (!DevExt->StorageStackDeviceObject) { IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(DevExt->AttachedToDeviceObject, Irp); } #if DBG if (DevExt->DriveLetter != DEBUG_VOLUME) { IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(DevExt->AttachedToDeviceObject, Irp); } #endif do { KEVENT waitEvent; // // 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)); if (!(IrpSp->Parameters.Create.Options & FILE_OPEN_BY_FILE_ID)) { FileName = ExAllocateFromPagedLookasideList(&gFileNameLookAsideList); if (!FileName) { KdPrint(("sfilter!SfCreate: ExAllocatePoolWithTag failed\n")); Status = STATUS_INSUFFICIENT_RESOURCES; break; } SfGetFileNameFromFileObject(DevExt, FileObject, &FileNameLength, FileName); if (0 == _wcsnicmp(&FileName[3], SF_ENCRYPT_INFO_DIR, SF_ENCRYPT_INFOR_DIR_LENGTH)) { // // We deny all create request to our encrypt info dir except kernel mode // if (KernelMode == Irp->RequestorMode) { ExFreeToPagedLookasideList(&gFileNameLookAsideList, FileName); status = Irp->IoStatus.Status; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return status; } else { Status = STATUS_NO_SUCH_FILE; break; } } else { if (IrpSp->Parameters.Create.Options & FILE_DIRECTORY_FILE) { // // We don't care about directories // ExFreeToPagedLookasideList(&gFileNameLookAsideList, FileName); status = Irp->IoStatus.Status; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return status; } } } else { if (IrpSp->Parameters.Create.Options & FILE_DIRECTORY_FILE) { // // We don't care about directories // status = Irp->IoStatus.Status; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return status; } } //Status = SfForwardIrpSyncronously(DevExt->AttachedToDeviceObject, Irp); //if (NT_SUCCESS(Status) && (STATUS_REPARSE != Status)) { if((Irp->IoStatus.Information == FILE_CREATED) || (Irp->IoStatus.Information == FILE_OPENED)) { FILE_CONTEXT FileCtx; PFILE_CONTEXT FileCtxPtr = NULL; BOOLEAN NewElement = FALSE; FileCtx.FsContext = FileObject->FsContext; ExAcquireFastMutex(&DevExt->FsCtxTableMutex); FileCtxPtr = RtlLookupElementGenericTable(&DevExt->FsCtxTable, &FileCtx); if (FileCtxPtr) ++FileCtxPtr->RefCount; else { FileCtxPtr = RtlInsertElementGenericTable( &DevExt->FsCtxTable, &FileCtx, sizeof(FILE_CONTEXT), &NewElement ); FileCtxPtr->RefCount = 1; ASSERT(FileName); wcscpy(FileCtxPtr->Name, FileName); KeInitializeEvent(&FileCtxPtr->Event, SynchronizationEvent, TRUE); } ExReleaseFastMutex(&DevExt->FsCtxTableMutex); if(!_wcsnicmp(FileName,L"D:\\Test\\",8)) { if ((NodeType(FileObject->FsContext) == FAT_NTC_DCB) || (NodeType(FileObject->FsContext) == FAT_NTC_ROOT_DCB) || (NodeType(FileObject->FsContext) == NTFS_NTC_DCB) || (NodeType(FileObject->FsContext) == NTFS_NTC_ROOT_DCB)) { if (FileName) ExFreeToPagedLookasideList(&gFileNameLookAsideList, FileName); status = Irp->IoStatus.Status; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return status; } ExInitializeWorkItem(&WorkerCtx.WorkItem, SfWriteEncryptFlag, &WorkerCtx); WorkerCtx.DeviceObject = DeviceObject; WorkerCtx.FileObject = FileObject; KeInitializeEvent(&WorkerCtx.Event, NotificationEvent, FALSE); WorkerCtx.FileContext = FileCtxPtr; if( Irp->IoStatus.Information == FILE_CREATED ) { if (KeGetCurrentIrql() == PASSIVE_LEVEL) SfWriteEncryptFlag(&WorkerCtx); else { ExQueueWorkItem(&WorkerCtx.WorkItem, DelayedWorkQueue); KeWaitForSingleObject(&WorkerCtx.Event, Executive, KernelMode, FALSE, NULL); } } } } } }while(FALSE); // // Save the status and continue processing the IRP // if (FileName) ExFreeToPagedLookasideList(&gFileNameLookAsideList, FileName); status = Irp->IoStatus.Status; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return status; } static NTSTATUS MyIrpComplete( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context ) { UNREFERENCED_PARAMETER( DeviceObject ); UNREFERENCED_PARAMETER( Context ); // *Irp->UserIosb = Irp->IoStatus; // Copy status information to // the user if (Irp->MdlAddress) { MmUnmapLockedPages( MmGetSystemAddressForMdl(Irp->MdlAddress), Irp->MdlAddress); MmUnlockPages(Irp->MdlAddress); IoFreeMdl(Irp->MdlAddress); Irp->MdlAddress = NULL; } KeSetEvent(Irp->UserEvent, 0, FALSE); // Signal event IoFreeIrp(Irp); // Free IRP return STATUS_MORE_PROCESSING_REQUIRED; // Tell the I/O manager to stop } NTSTATUS SfIssueReadWriteIrpSynchronously( IN PDEVICE_OBJECT DeviceObject, IN PFILE_OBJECT FileObject, IN ULONG MajorFunction, IN PIO_STATUS_BLOCK IoStatus, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER ByteOffset, IN ULONG IrpFlags ) { PIRP Irp = NULL; PIO_STACK_LOCATION IrpSp = NULL; KEVENT Event; NTSTATUS Status; //FILE_STANDARD_INFORMATION StandardInformation; UNREFERENCED_PARAMETER( IrpFlags ); ASSERT((MajorFunction == IRP_MJ_READ) || (MajorFunction == IRP_MJ_WRITE)); KeInitializeEvent(&Event, NotificationEvent, FALSE); Irp = IoBuildAsynchronousFsdRequest( MajorFunction, DeviceObject, Buffer, Length, ByteOffset, IoStatus ); if (!Irp) return STATUS_INSUFFICIENT_RESOURCES; Irp = IoAllocateIrp( DeviceObject->StackSize, FALSE ); if (Irp == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } Irp->Flags = 0x43; Irp->UserEvent = &Event; IrpSp = IoGetNextIrpStackLocation(Irp); IrpSp->FileObject = FileObject; Irp->IoStatus.Information = 0; IoSetCompletionRoutine(Irp, &MyIrpComplete, 0, TRUE, TRUE, TRUE); Status = IoCallDriver(DeviceObject, Irp); if (STATUS_PENDING == Status) { KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); } //IoCompleteRequest( Irp, IO_NO_INCREMENT ); KdPrint(("SfIssueReadWriteIrpSynchronously! MajorFunction = %x, Buffer = %s, Length = %d\n",MajorFunction, Buffer, Length)); return IoStatus->Status; } NTSTATUS SfWriteEncryptFlag(IN PVOID Context) { PPOST_CREATE_WORKER_CONTEXT WorkerCtx = Context; NTSTATUS Status; IO_STATUS_BLOCK IoStatus={0}; UCHAR Buff[13]= "测试用的标记"; LARGE_INTEGER ByteOffset; PFILE_CONTEXT FileCtxPtr = WorkerCtx->FileContext; KeWaitForSingleObject(&FileCtxPtr->Event, Executive, KernelMode, FALSE, NULL); KdPrint(("SfWriteEncryptFlag! WorkerCtx.FileContext->Name = %ws\n", WorkerCtx->FileContext->Name)); ByteOffset.QuadPart = 0; IoStatus.Status = STATUS_SUCCESS; IoStatus.Information = 0; Status =SfIssueReadWriteIrpSynchronously(WorkerCtx->DeviceObject ,WorkerCtx->FileObject,IRP_MJ_WRITE,&IoStatus,Buff, 12,&ByteOffset,0); if (!NT_SUCCESS(Status)) { KdPrint(("SFilter!SfWriteEncryptFlag ERROR: %s\n\n", Buff)); } KeSetEvent(&FileCtxPtr->Event, IO_NO_INCREMENT, FALSE); KeSetEvent(&WorkerCtx->Event, IO_NO_INCREMENT, FALSE); return Status; } |
|
地板#
发布于:2009-02-26 17:09
忘了说一下具体的症状,在SfWriteEncryptFlag这个函数运行之后,是有对应的fileOject进入了我的sfwrite中的,而sfwrite中的buffer也可以看到自己传下来的内容(不过不知道边界有没有处理好),然而运行完sfwrite后文件内容还是空的,什么也没写进去。我也试过去掉自己写的sfwrite程序,结果也一样。
|
|
地下室#
发布于:2009-02-27 18:08
Irp = IoAllocateIrp( DeviceObject->StackSize, FALSE );
if (Irp == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } 这部分代码贴出来时忘了删掉,这部分是后来用IoBuildAsynchronousFsdRequest()失败后想试下用的,误导了大侠,真是 我决定听从大侠的意见,试一下MiniFilter和ZwWriteFile。非常感谢热心的michaelgz 大侠。 |
|
5楼#
发布于:2009-03-01 20:30
looksail大侠你好,判断文件名有什么特殊含义吗?可否详细讲讲。在我的理解里,在create里面将文件名提出来是给将来read,write和cleanup的函数用的,大侠特意说的判断文件名是有什么我完全没注意到的地方吗?
|
|