文件操作---学mengwuji驱动编程笔记

第六课  读写磁盘文件


相关内核API


ZwCreateFile
是一个打开文件,这个AIP既可以创建一个,也可以打开文件,他具备创建和打开两种功能,共11个参数
NTSTATUS ZwCreateFile(//有11个参数
  _Out_     PHANDLE FileHandle,//1.handle类型的指针,提供这个函数的,让这个函数输入一个句柄给我们,这个
句柄就是一个文件句柄,以后
我们对这个文件进行操作全部用过这个FileHandle来进行的.
  _In_      ACCESS_MASK DesiredAccess,//2.描述访问的状态,我们以哪种权限访问的,比如我们以只读,可读可写
的,全部权限的形式进行访
问(GENERIC_ALL).
  _In_      POBJECT_ATTRIBUTES ObjectAttributes,//3.这是一个对象的属性,他是一个结构,_OBJECT_ATTRIBUTES//
结构在下面
  _Out_     PIO_STATUS_BLOCK IoStatusBlock,//4.返回值,代表,比如我们创建一个文件,创建好了,返回之后我们
就可以看这个文件的访问权
限,对这个文件可以创建,或者对这个文件可以打开,或者对这个文件干什么其他的一些东西.
  _In_opt_  PLARGE_INTEGER AllocationSize,//5.这个就是分配的大小值,一个指针,该数指定为文件初始分配时
的大小.
  _In_      ULONG FileAttributes,//6.文件的一些属性啊,这个文件假如是我们创建的一个文件的话,那我们指定
这些文件的属性,等一会编程
的时候再说.
  _In_      ULONG ShareAccess,//7.共享的一些属性,我们创建之后呢,别的程序对这个文件进行访问的话,他是以
哪种权限进行的,共享读,共
享写,或者是共享删除.
  _In_      ULONG CreateDisposition,//8.文件附加的一些属性,指定一个文件,如果这个文件不存在,那么取下面
的这个值,(FILE_OPEN_IF)
  _In_      ULONG CreateOptions,//9.控制打开操作和句柄标志位
  _In_opt_  PVOID EaBuffer,//10.附加的一个扩展描述的区域,
  _In_      ULONG EaLength//11.填写0
);
在写代码的时候的参数----以下带&的需要设置变量,其他都是常量值
Status=ZwCreateFile(&hFile,//1.句柄
        GENERIC_ALL,//2.访问权限
&FileObjAttr,//3.包含了创建路径和名字
//RtlInitUnicodeString(&usFileName,L"\\??\\c:\\1.txt");-->memset(&FileObjAttr,0,sizeof(OBJECT_ATTRIBUTES))
;//初始化清零
//--->InitializeObjectAttributes(&FileObjAttr,&usFileName,OBJ_CASE_INSENSITIVE,NULL,NULL);
//这个个宏来的,OBJ_CASE_INSENSITIVE(对大小写不敏感)  
&IoStatusBlock,//4.这参数不用管,后面也用不到
NULL,//5.创建文件的时候分配的大小,比如分配1m或者1kb大小
FILE_ATTRIBUTE_NORMAL,// 6.
FILE_SHARE_READ,//7.共享读
FILE_OPEN_IF,//8.如果不存在这个文件,我们就创建,如果存在的话我就打开
FILE_NON_DIRECTORY_FILE,//9.这个文件不是一个目录,FILE_DIRECTORY_FILE  这是一个目录
NULL,//10.不用管
0
                 );


typedef struct _OBJECT_ATTRIBUTES {//共6个参数
  ULONG           Length;//1.文件的长度
  HANDLE          RootDirectory;//2.文件的根目录
  PUNICODE_STRING ObjectName;//3.文件名字----我们只关心这个,我们创建的名字是什么,这里就要写入名字,这
个是必须写上的
  ULONG           Attributes;//4.文件属性
  PVOID           SecurityDescriptor;//5.安全相关的
  PVOID           SecurityQualityOfService;//6.安全相关的
}  OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;


初始化ObjectAttributes需用用到宏InitializeObjectAttributes--共5个参数
#define InitializeObjectAttributes( p, n, a, r, s ) { \
    (p)->Length = sizeof( OBJECT_ATTRIBUTES );          \
    (p)->RootDirectory = r;                             \
    (p)->Attributes = a;                                \
    (p)->ObjectName = n;                                \
    (p)->SecurityDescriptor = s;                        \
    (p)->SecurityQualityOfService = NULL;               \
    }




//参数
P,我们提供的这个结构体
n,初始化的时候指定的名字,ObjectName
a,Attributes 文件的属性
r,根目录
s,文件的一些安全描述之类的


编程目的的不同,我们可以写入很多值,一般情况下,我们写入的值是固定的,只需要写入少数的几个值,这个函数返回
0的话,说明这个函数调用成
功了,如果返回一个非0值的话,就代表一个错误码,你可以去头文件当中看这个创建为什么是错误的,//


ZwOpenFile
这个API只能打开文件,既然已经有ZwCreateFile,为什么还需要一个打开文件呢,为什么微软还提供ZwOpenFile,因为
ZwOpenFile的函数比较简
单一点,ZwCreateFile参数比较麻烦一点.


NTSTATUS ZwOpenFile(//6个参数
  _Out_  PHANDLE FileHandle,//1.打开文件的句柄
  _In_   ACCESS_MASK DesiredAccess,//2.打开文件的权限,以只读,可读可写的
  _In_   POBJECT_ATTRIBUTES ObjectAttributes,//3.这是一个对象的属性,他是一个结构,_OBJECT_ATTRIBUTES
  _Out_  PIO_STATUS_BLOCK IoStatusBlock,//4.返回值,代表,比如我们创建一个文件,创建好了,返回之后我们就
可以看这个文件的访问权限,对这个文件可以创建,或者对这个文件可以打开,或者对这个文件干什么其他的一些东西
.
  _In_   ULONG ShareAccess,//5.共享的一些属性,我们创建之后呢,别的程序对这个文件进行访问的话,他是以哪
种权限进行的,共享读,共享写,或者是共享删除.
  _In_   ULONG OpenOptions//6.打开文件时指定要应用的选项---打开一个标志要参考ZwCreateFile的第9个参数
,FILE_NON_DIRECTORY_FILE,//这个//文件不是一个目录,FILE_DIRECTORY_FILE  这是一个目录
);
Status=ZwOpenFile(
&hsFile,//1.句柄
GENERIC_ALL,//2.访问权限
&FileObjAttr,//3.包含了创建路径和名字
&IoStatusBlock,//4.这参数不用管,后面也用不到
FILE_SHARE_READ,//5.共享读
FILE_NON_DIRECTORY_FILE//6.这个文件不是一个目录,FILE_DIRECTORY_FILE---这是一个目录
);
ZwSetInforMationFile
这是设置文件的一些信息,比如说他的文件名字,他创建的时间,他的大小,等等一些信息,我们都可以用这个函数进行
设置.
如果我们没有先查询(ZwQueryInformationFile)的话,直接就设置(ZwSetInforMationFile)文件信息为我们的属性的
话,会把本来的
属性给淹没掉的,可能会导致错误,也可能会导致修改不了,所以呢,为了安全起见,在设置之前,我们进行查询(ZwQueryInformationFile)
一下
NTSTATUS ZwSetInformationFile(//有5个参数
  _In_   HANDLE FileHandle,//文件句柄
  _Out_  PIO_STATUS_BLOCK IoStatusBlock,//输出参数
  _In_   PVOID FileInformation,//一个结构体的指针,是根据最后一个参数FILE_INFORMATION_CLASS//这个参数
来指定的FileInformation
//到底是什么结构体
  _In_   ULONG Length,//---第三个参数FileInformation//这个结构体的大小
  _In_   FILE_INFORMATION_CLASS FileInformationClass//有很多种取值,根据不同的取值设定不同的信息,比如

//,如果指定为 FileBasicInformation的话,msdn上面共有10种取值.
);




结构体FileBasicInformation
typedef struct _FILE_BASIC_INFORMATION {
  LARGE_INTEGER CreationTime;//创建的时间
  LARGE_INTEGER LastAccessTime;//上次访问的时间
  LARGE_INTEGER LastWriteTime;//最后修改文件的时间
  LARGE_INTEGER ChangeTime;//改变的时间
  ULONG         FileAttributes;//(在msdn上有17个属性值)文件的属性,文件拥有可写属性,可读属性等等,
//这里根据不同的值可以设置一些文件的属性
//这个参数,在我们设置文件的属性之前,文件本来就具备一些属性的,一般具备可读可写的属性,&Fbi,我们要设置的
话,首先要获取
//文件本来是什么属性,然后再进行一些修改,如果直接设置的话,可能会设置失败的,所以呢,如果要设置文件的属性
之前,需要用
//ZwQueryInformationFile//来进行一些查询工作
} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;


ZwQueryInformationFile
查询文件的一些信息,比如说时间啊,名字啊之类的.


NTSTATUS ZwQueryInformationFile(//有5个参数跟ZwSetInformationFile的参数差不多
  _In_   HANDLE FileHandle,//文件句柄
  _Out_  PIO_STATUS_BLOCK IoStatusBlock,//输出参数
  _In_   PVOID FileInformation,//一个结构体的指针,是根据最后一个参数FILE_INFORMATION_CLASS//这个参数
来指定的FileInformation
//到底是什么结构体
  _In_   ULONG Length,//---第三个参数FileInformation//这个结构体的大小
  _In_   FILE_INFORMATION_CLASS FileInformationClass//有很多种取值,根据不同的取值设定不同的信息,比如

//,如果指定为 FileBasicInformation的话,msdn上面共有10种取值.
);




ZwReadFile
读取文件


NTSTATUS ZwReadFile(//有9个参数
  _In_      HANDLE FileHandle,//1.句柄
  _In_opt_  HANDLE Event,//2.事件,读操作是否完成了,如果这个读信号完成了,就会把这个事件置成有信号的,一
般填写NULL
  _In_opt_  PIO_APC_ROUTINE ApcRoutine,//3.如果是设备或者是中间层驱动的话,你可以指定这个参数为NULL,
//这个读操作如果完成的话,你给他一个APC历程,APC实际上是一种,和第二个参数事件(Event)差不多功能
  _In_opt_  PVOID ApcContext,//4.APC历程的参数,直接写NULL就可以了
  _Out_     PIO_STATUS_BLOCK IoStatusBlock,//5.返回读完成的一些状态,你用这个结构去接收一些完成的状态
信息,然后呢
//这个结构下面的参数Information是接收从文件读了多少个字节
  _Out_     PVOID Buffer,//6.就是我们提供的一个读的缓冲区,输出的参数
  _In_      ULONG Length,//7.我们读取的长度
  _In_opt_  PLARGE_INTEGER ByteOffset,//8.读的偏移,从多少个偏移量开始读,意思是从哪个位置开始读.
//记住啊PLARGE_INTEGER//是一个结构赋值的时候需要ReadOffset.QuadPart=0;(表示从第1个开始读)
  _In_opt_  PULONG Key//9.设置为NULL.
);
ZwWriteFile
写入一个文件


NTSTATUS ZwWriteFile(//有9个参数
  _In_      HANDLE FileHandle,//1.句柄
  _In_opt_  HANDLE Event,//2.事件,写入操作是否完成了,如果这个读信号完成了,就会把这个事件置成有信号的
,一般填写NULL
  _In_opt_  PIO_APC_ROUTINE ApcRoutine,//3.如果是设备或者是中间层驱动的话,你可以指定这个参数为NULL,
//这个写入操作如果完成的话,你给他一个APC历程,APC实际上是一种,和第二个参数事件(Event)差不多功能
  _In_opt_  PVOID ApcContext,//4.APC历程的参数,直接写NULL就可以了
  _Out_     PIO_STATUS_BLOCK IoStatusBlock,//5.返回写入完成的一些状态,你用这个结构去接收一些完成的状
态信息,然后呢
//这个结构下面的参数Information是接收从文件读了多少个字节
  _Out_     PVOID Buffer,//6.就是我们提供的一个写入的缓冲区,输出的参数
  _In_      ULONG Length,//7.我们写入的长度
  _In_opt_  PLARGE_INTEGER ByteOffset,//8.写入的偏移,从多少个偏移量开始写入,意思是从哪个位置开始写入
.
//记住啊PLARGE_INTEGER//是一个结构赋值的时候需要ReadOffset.QuadPart=0;(表示从第1个开始读)
  _In_opt_  PULONG Key//9.设置为NULL.
);

你可能感兴趣的:(编程,文件操作,内核)