|
阅读:3393回复: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;
} |
|
最新喜欢:
|
|
沙发#
发布于: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; 这两种有区别么 |
|