void FileTest()
{
    //进行文件相关操作
    
    //创建文件
    CreateFileTest();

    //打开文件
    OpenFileTest();

    //修改或获取文件属性
    ModifyFileAttributesTest();

    //读写文件
    ReadFileTest();
    WriteFileTest();
}
void CreateFileTest()
{
    OBJECT_ATTRIBUTES objectAttributes;
    //创建一个OBJECT_ATTRIBUTES对象,专门用来给别的对象配置属性
    IO_STATUS_BLOCK iostatus;
    //该结构体接受ZwCreateFile创建文件对象的结果
    HANDLE hFile;
    //定义一个文件句柄
    UNICODE_STRING logFileUnicodeString;
    //用来保存文件地址
    RtlInitUnicodeString(&logFileUnicodeString, L"\\??\\C:\\1.log");
    //或者是\\Device\\HarddiskVolume1\\1.LOG"也行
    
    //初始化objectAttributes
    InitializeObjectAttributes(&objectAttributes,
        &logFileUnicodeString,
        OBJ_CASE_INSENSITIVE,
        NULL,
        NULL);
    //创建文件
    NTSTATUS ntStatus = ZwCreateFile(&hFile,
        GENERIC_WRITE,
        &objectAttributes,
        &iostatus,
        NULL,
        FILE_ATTRIBUTE_NORMAL,
        FILE_SHARE_READ,
        FILE_OPEN_IF,//有就打开没有就关闭
        FILE_SYNCHRONOUS_IO_NONALERT,
        NULL,
        0);
    if (NT_SUCCESS(ntStatus))//如果获取文件句柄成功
    {
        KdPrint(("创建文件成功\n"));
    }
    else
    {
        KdPrint(("创建文件失败\n"));
    }
    ZwClose(hFile);
}

void OpenFileTest()
{
    OBJECT_ATTRIBUTES objectAttributes;
    IO_STATUS_BLOCK iostatus;
    HANDLE hFile;
    UNICODE_STRING logFileUnicodeString;

    //初始化字符串
    RtlInitUnicodeString(&logFileUnicodeString, L"\\Device\\HarddiskVolume1\\1.LOG");

    //初始化objectAttributes
    InitializeObjectAttributes(&objectAttributes,
        &logFileUnicodeString,
        OBJ_CASE_INSENSITIVE,
        NULL,
        NULL);
    
    //创建文件
    NTSTATUS ntStatus = ZwCreateFile(&hFile,
        GENERIC_READ,
        &objectAttributes,
        &iostatus,
        NULL,
        FILE_ATTRIBUTE_NORMAL,
        FILE_SHARE_READ,
        FILE_OPEN,//只打开,如果没有就报错
        FILE_SYNCHRONOUS_IO_NONALERT,
        NULL,
        0);
    if (NT_SUCCESS(ntStatus))
    {
        KdPrint(("Open file Successfully!\n"));
    }
    else
    {
        KdPrint(("Open file unsuccessfully!\n"));
    }

    //文件操作
    //.....

    ZwClose(hFile);
}

void ModifyFileAttributesTest()
{
    OBJECT_ATTRIBUTES objectAttributes;
    IO_STATUS_BLOCK iostatus;
    HANDLE    hFile;
    UNICODE_STRING logFileUnicodeString;

    //初始化UNICODE_STRING字符串
    RtlInitUnicodeString(&logFileUnicodeString,
        L"\\??\C:\\1.log");
    //\\Device\\HarddiskVolume1\\1.LOG也是可以的

    //初始化objectAttributes
    InitializeObjectAttributes(&objectAttributes,
        &logFileUnicodeString,
        OBJ_CASE_INSENSITIVE,
        NULL,
        NULL);

    //创建文件
    NTSTATUS ntStatus = ZwCreateFile(&hFile,
        GENERIC_READ,
        &objectAttributes,
        &iostatus,
        NULL,
        FILE_ATTRIBUTE_NORMAL,
        0,
        FILE_OPEN,
        FILE_SYNCHRONOUS_IO_NONALERT,
        NULL,
        0);
    if (NT_SUCCESS(ntStatus))
    {
        KdPrint(("Open File Successfully!\n"));
    }

    FILE_STANDARD_INFORMATION fsi;
    //读取文件长度
    ntStatus = ZwQueryInformationFile(hFile,
        &iostatus,
        &fsi,
        sizeof(FILE_STANDARD_INFORMATION),
        FileStandardInformation);
    if (NT_SUCCESS(ntStatus))
    {
        KdPrint(("File Length:%u\n", fsi.EndOfFile.QuadPart));
    }

    //修改当前文件指针
    FILE_POSITION_INFORMATION fpi;
    fpi.CurrentByteOffset.QuadPart = 100i64;
    ntStatus = ZwSetInformationFile(&hFile,
        &iostatus,
        &fpi,
        sizeof(FILE_POSITION_INFORMATION),
        FilePositionInformation);
    if (NT_SUCCESS(ntStatus))
    {
        KdPrint(("Update the file pointer successfully\n"));
    }

    //关闭句柄
    ZwClose(hFile);
}

void WriteFileTest()//ZwWriteFile
{
    
    OBJECT_ATTRIBUTES objectAttributes;
    IO_STATUS_BLOCK iostatus;
    HANDLE hFile;
    UNICODE_STRING logFileUnicodeString;

    //初始化UNICODE_STRING字符串
    RtlInitUnicodeString(&logFileUnicodeString,
        L"\\??\\C:\\1.log");

    //初始化objectAttributes
    InitializeObjectAttributes(&objectAttributes,
        &logFileUnicodeString,
        OBJ_CASE_INSENSITIVE,
        NULL,
        NULL);

    //创建文件
    NTSTATUS ntStatus = ZwCreateFile(&hFile,
        GENERIC_WRITE,
        &objectAttributes,
        &iostatus,
        NULL,
        FILE_ATTRIBUTE_NORMAL,
        FILE_SHARE_WRITE,
        FILE_OPEN_IF,//即使该文件存在也创建
        FILE_SYNCHRONOUS_IO_NONALERT,
        NULL,
        0);
#define BUFFER_SIZE 1024
    PUCHAR pBuffer = (PUCHAR)ExAllocatePool(PagedPool, BUFFER_SIZE);
    //给缓冲区分配内存
    RtlFillMemory(pBuffer, BUFFER_SIZE, 0XAA);//用0xAA填充缓冲区
    KdPrint(("The program will write %d bytes\n", BUFFER_SIZE));

    //将缓冲区写入到文件里
    ZwWriteFile(hFile, NULL, NULL, NULL, &iostatus, pBuffer, BUFFER_SIZE,
        NULL, NULL);
    KdPrint(("The Program really wrote %d bytes\n", iostatus.Information));

    //构造要填充的数据
    RtlFillMemory(pBuffer, BUFFER_SIZE, 0XBB);
    KdPrint(("the program will append %d bytes\n", BUFFER_SIZE));

    //追加数据
    LARGE_INTEGER number;
    number.QuadPart = 1024i64;//设置文件指针
    //对文件进行附加写
    ZwWriteFile(hFile, NULL, NULL, NULL, &iostatus, pBuffer, BUFFER_SIZE, &number,NULL);
    KdPrint(("The program really appended %d bytes\n", iostatus.Information));

    //关闭文件句柄
    ZwClose(hFile);

    //释放缓冲区
    ExFreePool(pBuffer);
}

void ReadFileTest()
{
    //也是采用的ZwWriteFile    API
    OBJECT_ATTRIBUTES objectAttributes;
    IO_STATUS_BLOCK iostatus;
    HANDLE hFile;
    UNICODE_STRING logFileUnicodeString;

    //初始化UNICODE_STRING字符串
    RtlInitUnicodeString(&logFileUnicodeString, L"\\??\\C:\\1.log");

    //初始化objectAttributes
    InitializeObjectAttributes(&objectAttributes,
        &logFileUnicodeString,
        OBJ_CASE_INSENSITIVE,
        NULL,
        NULL);

    //得到文件句柄
    NTSTATUS ntStatus = ZwCreateFile(&hFile,
        GENERIC_READ,
        &objectAttributes,
        &iostatus,
        NULL,
        FILE_ATTRIBUTE_NORMAL,
        FILE_SHARE_READ,
        FILE_OPEN,//即使存在也创建
        FILE_SYNCHRONOUS_IO_NONALERT,
        NULL,
        0);
    if (!NT_SUCCESS(ntStatus))
    {
        KdPrint(("The File is not exist!\n"));
        return;
    }
    
    FILE_STANDARD_INFORMATION fsi;
    //读取文件长度
    ntStatus = ZwQueryInformationFile(hFile,
        &iostatus,
        &fsi,
        sizeof(FILE_STANDARD_INFORMATION),
        FileStandardInformation);
    KdPrint(("The program want to read %d bytes\n", fsi.EndOfFile.QuadPart));
    
    //为读取的文件分配缓冲区
    PUCHAR pBuffer = (PUCHAR)ExAllocatePool(PagedPool, (LONG)fsi.EndOfFile.QuadPart);

    //读取文件
    ZwReadFile(hFile, NULL, NULL,NULL,
        &iostatus,
        pBuffer,
        (LONG)fsi.EndOfFile.QuadPart,
        NULL, NULL);

    KdPrint(("The Program really read %d bytes\n", iostatus.Information));

    //关闭文件句柄
    ZwClose(hFile);

    //释放缓冲区
    ExFreePool(pBuffer);

}