文件系统驱动开发实例

文件系统驱动开发实例

本文将介绍一个文件系统开发的实例,这个实例的功能比较简单,仅供个人娱乐之用,请高手们笑而置之。

   本例的基本功能是对目录的保护,就是对一个目录设置密码,使之不让访问,不过实现的方法是在底层判断,还是调试了好久呢。程序模块分为上层应用程序和下层驱动程序,上层是对一些设置数据的保存,下层就是过滤和判断。为了让程序再重启之后还有效,特意又加了一个服务来load设置。下面就来分享一下底层的code

写过驱动的朋友都知道IRP_MJ_DEVICE_CONTROL吧,这里是上层对下层的一些设置,主要就是文件名,目录名,密码之类的。

NTSTATUS DeviceControl(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)

{

        PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);

       

        NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;

        //ULONG OutputLength   = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;

        PSFILTER_DEVICE_EXTENSION DevExt = (PSFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

        if(g_DeviceObject != DeviceObject)

        {

               

                IrpStack = IoGetCurrentIrpStackLocation(Irp);

                IoSkipCurrentIrpStackLocation(Irp);

                return IoCallDriver( DevExt->NLExtHeader.AttachedToDeviceObject, Irp);

        }

       

        switch( IrpStack->Parameters.DeviceIoControl.IoControlCode)

        {

        case IOCTL_SETFILES:

                {

                        PFILE_ELEMENT Buffer = (PFILE_ELEMENT)Irp->AssociatedIrp.SystemBuffer;

                        ULONG InputLength    = IrpStack->Parameters.DeviceIoControl.InputBufferLength;

                        PFILE_LIST pdElement;

                        PLIST_ENTRY pListEntry;

                        BOOLEAN bNewElement=TRUE;

                        if( (Buffer==0) || (InputLength < sizeof(FILE_ELEMENT)))

                        {

                                status = STATUS_INVALID_PARAMETER;

                                break;

                        }

                       

                        if(!IsListEmpty(&FilterFileListHead))

                                for (pListEntry = FilterFileListHead.Flink; pListEntry != &FilterFileListHead; pListEntry = pListEntry->Flink)

                                {                                     

                                       

                                       

                                        pdElement = CONTAINING_RECORD(pListEntry, FILE_LIST, linkfield);

                                        if (_wcsicmp(pdElement->fileElement.szFileName,Buffer->szFileName)==0)

                                        {

                                                bNewElement=FALSE;

                                               

                                                break;

                                        }

                                       

                                       

                                       

                                }

                                if (bNewElement)

                                {

                                        PFILE_LIST pdElement = (PFILE_LIST) ExAllocatePool(NonPagedPool, sizeof(FILE_LIST));

                                        RtlCopyMemory(&pdElement->fileElement,Buffer,sizeof(FILE_ELEMENT));

                                        InsertTailList(&FilterFileListHead, &pdElement->linkfield);  

                                        KdPrint(("IOCTL_SETFILES--:%wZ",Buffer->szFileName));

                                       

                                }

                               

                                status = STATUS_SUCCESS;

                                break;

                }

        case IOCTL_DELFILES:

                {

                        PFILE_ELEMENT Buffer = (PFILE_ELEMENT)Irp->AssociatedIrp.SystemBuffer;

                        ULONG InputLength    = IrpStack->Parameters.DeviceIoControl.InputBufferLength;

                        PFILE_LIST pdElement;

                        PLIST_ENTRY pListEntry;

                        if( (Buffer==0) || (InputLength < sizeof(FILE_ELEMENT)))

                        {

                                status = STATUS_INVALID_PARAMETER;

                                break;

                        }

                       

                        if(!IsListEmpty(&FilterFileListHead))

                                for (pListEntry = FilterFileListHead.Flink; pListEntry != &FilterFileListHead; pListEntry = pListEntry->Flink)

                                {                                     

                                       

                                       

                                        pdElement = CONTAINING_RECORD(pListEntry, FILE_LIST, linkfield);

                                        if (_wcsicmp(pdElement->fileElement.szFileName,Buffer->szFileName)==0)

                                        {

                                                RemoveEntryList(pListEntry);

                                                ExFreePool(pdElement);

                                                break;

                                        }

                                }

                        status = STATUS_SUCCESS;

                        break;

                }

        case IOCTL_SETFOLDERS:

                {

                        PFILE_ELEMENT Buffer = (PFILE_ELEMENT)Irp->AssociatedIrp.SystemBuffer;

                        ULONG InputLength    = IrpStack->Parameters.DeviceIoControl.InputBufferLength;

                        PFILE_LIST pdElement;

                        PLIST_ENTRY pListEntry;

                        BOOLEAN bNewElement=TRUE;

                        if( (Buffer==0) || (InputLength < sizeof(FILE_ELEMENT)))

                        {

                                status = STATUS_INVALID_PARAMETER;

                                break;

                        }

                       

                        if(!IsListEmpty(&FilterFolderListHead))

                                for (pListEntry = FilterFolderListHead.Flink; pListEntry != &FilterFolderListHead; pListEntry = pListEntry->Flink)

                                {                                     

                                       

                                       

                                        pdElement = CONTAINING_RECORD(pListEntry, FILE_LIST, linkfield);

                                        if (_wcsicmp(pdElement->fileElement.szFileName,Buffer->szFileName)==0)

                                        {

                                                bNewElement=FALSE;

                                                break;

                                        }

                                       

                                       

                                       

                                }

                                if (bNewElement)

                                {

                                        PFILE_LIST pdElement = (PFILE_LIST) ExAllocatePool(NonPagedPool, sizeof(FILE_LIST));

                                        RtlCopyMemory(&pdElement->fileElement,Buffer,sizeof(FILE_ELEMENT));

                                        InsertTailList(&FilterFolderListHead, &pdElement->linkfield);  

                               

                               

                                status = STATUS_SUCCESS;

                                break;

                }

        case IOCTL_DELFOLDERS:

                {

                        PFILE_ELEMENT Buffer = (PFILE_ELEMENT)Irp->AssociatedIrp.SystemBuffer;

                        ULONG InputLength    = IrpStack->Parameters.DeviceIoControl.InputBufferLength;

                        PFILE_LIST pdElement;

                        PLIST_ENTRY pListEntry;

                        if( (Buffer==0) || (InputLength < sizeof(FILE_ELEMENT)))

                        {

                                status = STATUS_INVALID_PARAMETER;

                                break;

                        }

                       

                        if(!IsListEmpty(&FilterFolderListHead))

                                for (pListEntry = FilterFolderListHead.Flink; pListEntry != &FilterFolderListHead; pListEntry = pListEntry->Flink)

                                {                                     

                                       

                                       

                                        pdElement = CONTAINING_RECORD(pListEntry, FILE_LIST, linkfield);

                                        if (_wcsicmp(pdElement->fileElement.szFileName,Buffer->szFileName)==0)

                                        {

                                                RemoveEntryList(pListEntry);

                                                ExFreePool(pdElement);

                                                break;

                                        }

                                }

                                status = STATUS_SUCCESS;

                                break;

                }

        case IOCTL_TEMPDEFILES:

                {

                        ULONG InputLength    = IrpStack->Parameters.DeviceIoControl.InputBufferLength;

                    TEMPDECODE        *Code = (TEMPDECODE*)Irp->AssociatedIrp.SystemBuffer;

                        if( (Code==0) || (InputLength < sizeof(TEMPDECODE)))

                        {

                                status = STATUS_INVALID_PARAMETER;

                                break;

                        }

                        wcscpy(TempCode.szFileName,Code->szFileName);

                        wcscpy(TempCode.szPwsd,Code->szPwsd);

                        status = STATUS_SUCCESS;

                        break;

 

                }

 

        default:

                status = STATUS_INVALID_DEVICE_REQUEST;

        }

       

        Irp->IoStatus.Status = STATUS_SUCCESS;

        Irp->IoStatus.Information = 0;

        IoCompleteRequest(Irp,IO_NO_INCREMENT);

        return status;

       

}

对文件的拦截主要是下面的code:

NTSTATUS

SfCreate (

    __in PDEVICE_OBJECT DeviceObject,

    __in PIRP Irp

    ){

/*省略*/

        if(FileObject->FileName.Buffer!=NULL)

        {

                PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp );

                PLIST_ENTRY pListEntry;

                PFILE_LIST pdElement;

                UNICODE_STRING  DosName;

                UNICODE_STRING Path;

                WCHAR TempBuf[256];

                WCHAR szPath[256]=L"";

                if(!IsListEmpty(&FilterFileListHead))

                {

                        if (FileObject->DeviceObject!=NULL)

                        {

                                IoVolumeDeviceToDosName(FileObject->DeviceObject,&DosName);

                                RtlInitEmptyUnicodeString(&Path,TempBuf,256*sizeof(WCHAR));

                                RtlCopyUnicodeString(&Path,&DosName);

                                RtlAppendUnicodeStringToString(&Path,&FileObject->FileName);

                                wcscpy(szPath,Path.Buffer);

                        //        KdPrint(("%wZ",&(FileObject->FileName)));

                                {

                                        ULONG        CreateDisposition = (irpSp->Parameters.Create.Options>> 24) & 0x000000ff;

                                        if((CreateDisposition==FILE_OPEN||CreateDisposition==FILE_OPEN_IF

                                                ||CreateDisposition==FILE_OVERWRITE))

                                        {

                               

                                               

                                        }

                                }

                       

                        {

                                        for (pListEntry = FilterFileListHead.Flink; pListEntry != &FilterFileListHead; pListEntry = pListEntry->Flink)

                                        {                                     

                                                pdElement = CONTAINING_RECORD(pListEntry, FILE_LIST, linkfield);

                                                if (_wcsicmp(pdElement->fileElement.szFileName,szPath)==0)

                                                {

                                               

                                                        {

                                                                        if((!(FILE_DELETE_ON_CLOSE&irpSp->Parameters.Create.Options)||

                                                                                !(FILE_OPEN_REPARSE_POINT&irpSp->Parameters.Create.Options)))

                                                                {

                                                                        if (_wcsicmp(pdElement->fileElement.szFileName,TempCode.szFileName)==0&&

                                                                                _wcsicmp(pdElement->fileElement.szPwsd,TempCode.szPwsd)==0)

                                                                        {

                                                                                LARGE_INTEGER duetime;

                                                                                KdPrint(("KeSetTimer"));

                                                                       

                                                                                 duetime.QuadPart = -10000*1000*10;

                                       // duetime=RtlConvertLongToLargeInteger(100*-50);

                                                                                KeSetTimer(&Timer, duetime,&Dpc);       

                                                                       

                                                                                break;

                                                                        }

                                                                        if (DosName.Buffer!=NULL)

                                                                                ExFreePool(DosName.Buffer);

                                                                        Irp->IoStatus.Status = STATUS_ACCESS_DENIED;

                                                                        Irp->IoStatus.Information = 0;

                                                                        IoCompleteRequest(Irp, IO_NO_INCREMENT);

                                                                        return STATUS_SUCCESS;

                                                                       

                                                                }

                                                        }

                                                       

                                                       

                                                }

                                        }

                                       

                                       

                                }//endif

                                if (DosName.Buffer!=NULL)

                                        ExFreePool(DosName.Buffer);

                        }

                }

               

               

        }

}

还有就是对目录的过滤部分,其实和文件的是一样的,由于代码太长就不再写了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值