阅读:3239回复:4
sfilter之目录隐藏代码,关键函数
如果你没有能力把这些函数用上,那说明:你还需要看基础教程,然后再回头看这个吧。
NTSTATUS ProcessHideDir(PDEVICE_OBJECT DeviceObject,PIRP Irp,PUNICODE_STRING Filename) { KEVENT event; PFILE_BOTH_DIR_INFORMATION QueryBuffer = NULL; PFILE_BOTH_DIR_INFORMATION PreQueryBuffer = NULL; ULONG NextOffset = 0; ULONG CurNoHideBufPos = 0; //当前项之前不需要隐藏的缓冲区长度. ULONG DirBufLen = 0; //用户缓冲区冲长度 ULONG AfterHideBufLen = 0; ULONG ulCurItemLen=0; //new func use BOOLEAN bIsHideFile =FALSE; BOOLEAN bLastOne=FALSE; PSGFILTER_DEVICE_EXTENSION devExt=(PSGFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension; PNAME_CONTROL pFullFileName; NTSTATUS Status; UNICODE_STRING ustrOnlyFileName;// no dirpath UNICODE_STRING ustrCurrentDir; UNICODE_STRING ustrParentDir; UNICODE_STRING ustrFolderCtlFile; UNICODE_STRING ustrUpperPath; PIO_STACK_LOCATION IrpSp=IoGetCurrentIrpStackLocation(Irp); RtlInitUnicodeString(&ustrCurrentDir,L"."); RtlInitUnicodeString(&ustrParentDir,L".."); RtlInitUnicodeString(&ustrFolderCtlFile,DRVDIRHIDESETFILE); Status =NLAllocateNameControl(&pFullFileName,&gSfNameBufferLookasideList); if(!NT_SUCCESS(Status)) { IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; } Status=NLReallocNameControl(pFullFileName,SG_MAX_PATH,NULL); if(!NT_SUCCESS(Status)) { IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; } while (TRUE) { KeInitializeEvent(&event, NotificationEvent, FALSE); IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp, ProcessHideDirCompletion, &event, TRUE, TRUE, TRUE); IoCallDriver(devExt->NLExtHeader.AttachedToDeviceObject, Irp); KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL); KeClearEvent(&event); if(!NT_SUCCESS(Irp->IoStatus.Status))// == STATUS_NO_SUCH_FILE) { IoCompleteRequest(Irp, IO_NO_INCREMENT); return Irp->IoStatus.Status; } DirBufLen = IrpSp->Parameters.QueryDirectory.Length; //从底层传入的目录信息缓冲区长度 AfterHideBufLen = DirBufLen; //Get the directory information link if (Irp->MdlAddress) { QueryBuffer = (PFILE_BOTH_DIR_INFORMATION)MmGetSystemAddressForMdl(Irp->MdlAddress); } else{ // QueryBuffer = (PFILE_BOTH_DIR_INFORMATION)Irp->UserBuffer; } //backup the querybuffer PreQueryBuffer = QueryBuffer; if ((!QueryBuffer) || (QueryBuffer->NextEntryOffset > DirBufLen) || QueryBuffer->FileNameLength == 0 )// 缓冲区为空 或 用户传入的缓冲区长度不够,或文件名为空 { IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver( devExt->NLExtHeader.AttachedToDeviceObject, Irp ); } bLastOne = FALSE; do //循环读取目录项 { bIsHideFile = FALSE; RtlCopyUnicodeString(&pFullFileName->Name,Filename); if( pFullFileName->Name.Buffer[pFullFileName->Name.Length/2-1] != L'\\')//处理盘符后的\符号 RtlAppendUnicodeToString(&pFullFileName->Name,L"\\"); ustrOnlyFileName.Buffer = QueryBuffer->FileName; ustrOnlyFileName.Length=(USHORT) QueryBuffer->FileNameLength; ustrOnlyFileName.MaximumLength = ustrOnlyFileName.Length; if( ustrOnlyFileName.Length>1) { if( ustrOnlyFileName.Buffer[0] == L'\\') { ustrOnlyFileName.Buffer+=1; ustrOnlyFileName.Length-=2; } } Status=RtlAppendUnicodeStringToString(&pFullFileName->Name,&ustrOnlyFileName); if( NT_SUCCESS(Status)) { RtlUpcaseUnicodeString(&ustrUpperPath,&pFullFileName->Name,TRUE); if((QueryBuffer->FileAttributes & FILE_ATTRIBUTE_ARCHIVE) == FILE_ATTRIBUTE_ARCHIVE) // 是文件 { if( RtlCompareUnicodeString(&ustrFolderCtlFile,&ustrOnlyFileName,TRUE) == 0) { bIsHideFile = TRUE; // 如果是目录控制文件,直接隐藏 } else if( SgFindFile(&ustrUpperPath,&bIsHideFile)) bIsHideFile = TRUE; else bIsHideFile = FALSE; } else if((QueryBuffer->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) { if((RtlCompareUnicodeString(&ustrCurrentDir,&ustrOnlyFileName,TRUE) != 0) && (RtlCompareUnicodeString(&ustrOnlyFileName,&ustrParentDir,TRUE) != 0)) { //if( !SgFindFile(&ustrUpperPath,&bIsHideFile)) // bIsHideFile = FALSE; //{ bIsHideFile=IsHideDirectory(&pFullFileName->Name,devExt); // SgAddFile(&pFullFileName->Name,bIsHideFile); //} } } RtlFreeUnicodeString(&ustrUpperPath); } NextOffset = QueryBuffer->NextEntryOffset; //下一个目录内容项(目录或文件)的偏移,也是当前项的长度 if ( bIsHideFile == TRUE)// 隐藏的目录 { if (0 == NextOffset) //没有下一个了 { PreQueryBuffer->NextEntryOffset = 0; AfterHideBufLen =CurNoHideBufPos; //设置新的长度等于前面没隐藏的长度 } else { RtlMoveMemory((PUCHAR) QueryBuffer, (PUCHAR) QueryBuffer + NextOffset, (DirBufLen - CurNoHideBufPos - NextOffset)); //old use block******** AfterHideBufLen -= NextOffset; //最终的长度要减去当前项的长度 } //end of "first if" of DO } else { //当前项不需要隐藏,那就算长度吧 CurNoHideBufPos += NextOffset; //计算前面没有隐藏的长度 if(NextOffset > 0)//有下一项,那就要修正 前一项 { PreQueryBuffer = QueryBuffer; QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) ((PUCHAR) QueryBuffer + NextOffset); } } } while (0 != NextOffset );//(0 != offset); Irp->IoStatus.Information = AfterHideBufLen; if( AfterHideBufLen > 0 ) // 非: 只有一项,且是隐藏的.... { break; } else Irp->IoStatus.Information = DirBufLen; } // end of while(TRUE) IoCompleteRequest(Irp, IO_NO_INCREMENT); Status=Irp->IoStatus.Status; NLFreeNameControl(pFullFileName,&gSfNameBufferLookasideList); return Status; } // // 目录内容隐藏处理的完成例程 // // NTSTATUS ProcessHideDirCompletion( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context ) { UNREFERENCED_PARAMETER(DeviceObject); UNREFERENCED_PARAMETER(Irp); KeSetEvent((PRKEVENT) Context, IO_NO_INCREMENT, FALSE); return STATUS_MORE_PROCESSING_REQUIRED; } |
|
最新喜欢:rhpeng
|
沙发#
发布于:2010-02-18 21:35
顶起~~ O(∩_∩)O谢谢~~~您知道我在找
|
|
板凳#
发布于:2010-02-19 13:26
嘿嘿,谢谢先
|
|
地板#
发布于:2010-02-25 11:15
谢谢马哥分享。看起来比原来那个简单点~~
|
|
地下室#
发布于:2010-03-16 16:47
znsoft 老大,为什么这几句
ustrOnlyFileName.Buffer = QueryBuffer->FileName; ustrOnlyFileName.Length=(USHORT) QueryBuffer->FileNameLength; ustrOnlyFileName.MaximumLength = ustrOnlyFileName.Length; 可以直接RtlInitUnicodeString(&ustrOnlyFileName,QueryBuffer->FileName); ustrOnlyFileName.Length = (USHORT) QueryBuffer->FileNameLength; 这两种有区别么 |
|