首页
社区
课程
招聘
[旧帖] [求助][求助]windows驱动编程文件读写问题 0.00雪花
发表于: 2011-6-27 00:35 2043

[旧帖] [求助][求助]windows驱动编程文件读写问题 0.00雪花

2011-6-27 00:35
2043
如果我想用ZwWriteFile函数在文件中写入我自己定义的中文,例
  UNICODE_STRING test;
  RtlInitUnicodeString( &test, 
    L"我是jsjscool");
我的方法是
  RtlFillMemory(pBuffer,1024,0xAA);//覆盖内存
  RtlCopyMemory (pBuffer,&test,sizeof(test));//复制自己定义的test测试数据
        ZwWriteFile(*,NULL,NULL,NULL,*,pBuffer,1024,NULL,NULL);//自己定义的部分参数以*号代替

运行的结果在txt文件中是乱码……请问我要怎样用内核函数才能将中文写入txt文件。

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (17)
雪    币: 12
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
#include <ntddk.h>
VOID Unload(IN PDRIVER_OBJECT object)
{
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryString)
{

        NTSTATUS ntstatus;
        HANDLE hFile=NULL;
        IO_STATUS_BLOCK iostatus;
        OBJECT_ATTRIBUTES oa;
        UNICODE_STRING desstring;
UNICODE_STRING usPath;
UNICODE_STRING Receive;
RtlInitUnicodeString(&usPath,L"\\??\\c:\\log.txt");

InitializeObjectAttributes(&oa,&usPath,OBJ_KERNEL_HANDLE,NULL,NULL );

ntstatus=ZwCreateFile(&hFile,
                                          GENERIC_READ|GENERIC_WRITE,
                                          &oa,
                                          &iostatus,
                                          NULL,
                                          FILE_ATTRIBUTE_NORMAL,
                                          FILE_SHARE_READ,
                                          FILE_OPEN_IF,
                                          FILE_RANDOM_ACCESS|FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_ALERT,
                                          NULL,
                                          0);

ntstatus=ZwWriteFile(hFile,
                                         NULL,
                                         NULL,
                                         NULL,
                                         &iostatus,
                                         usPath.Buffer,
                                         usPath.Length,
                                         NULL,
                                         0
                                         );

ZwClose(hFile);
DriverObject->DriverUnload=Unload;
return 1;
}

我想就不用我解释了吧,这个可以成功编绎的,
2011-6-27 02:36
0
雪    币: 9
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
可能我把问题没讲清楚,我想问怎样用ZwCreateFile函数,把“汉字”写入文件,比如我自己定义的“我是jsjscool”这串汉字……一般的英文增删改我都能应付的!
不过还是谢谢你!!
2011-6-27 11:03
0
雪    币: 100
活跃值: (30)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
RtlCopyMemory (pBuffer,&test,sizeof(test));//复制自己定义的test测试数据

这句有问题
2011-6-27 11:16
0
雪    币: 163
活跃值: (75)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
记事本另存为,编码方式设置成unicode格式的~
2011-6-27 12:46
0
雪    币: 9
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
不行,写的时候是这样写的……比如汉字“我”的GBK编码是0xCED2,写进去时只取D2(末尾两位),所以是写的时候就有问题了,跟查看方式无关的。
2011-6-27 12:54
0
雪    币: 9
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
感谢你回答我的问题……希望你回答的时候能告诉我有什么问题嘛!可能编译环境,或者配置关系,这句代码在我这运行没问题,我是按照wdk上的要求写的,有问题的话还希望你帮我指出!!
2011-6-27 12:59
0
雪    币: 193
活跃值: (64)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
8
本来是UNICODE,你按照ANSI对待了
2011-6-27 13:23
0
雪    币: 111
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
这个还好的了
2011-6-27 13:29
0
雪    币: 9
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
是啊,那要怎么改??
2011-6-27 13:33
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
RtlInitUnicodeString( &test, L"我是jsjscool");
是把test的指针指向 L"我是jsjscool",并修改长度域,你RtlCopyMemory (pBuffer,&test,sizeof(test))复制结构体没用,你应该复制test.Buffer,才是真正字符串的内容,test.Length就是字符串的长度(字节长度)。RtlCopyMemory (pBuffer,test.Buffer, test.Length),才是对的。
另外,我总觉得你写的代码怪怪的,文件操作函数是跟什么中文英文无关的,只跟数据相关,你只要给定Buffer和Lengh,ZwWriteFile就能把Buffer指向的长度Length的数据区写入文件中,至于写入什么他根本就不管,你完全可以ZwWriteFile(*,NULL,NULL,NULL,*,L"我是jsjscool",20,NULL,NULL);。
2011-6-27 14:04
0
雪    币: 9
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
你说的让我很多东西都清晰了!!非常感谢!但是我这样试过,还是无法写入中文的,ZwWriteFile(*,NULL,NULL,NULL,*,L"我是jsjscool",20,NULL,NULL);
直接这样也不行,出来的还是乱码
2011-6-27 14:15
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
不是吧,难道是我弄错了?你要不把写文件的那整段源码发出来吧,我可以给你试试。
2011-6-27 14:23
0
雪    币: 143
活跃值: (61)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
14
ZwWriteFile (*, ......, "成功!", 6, ...);
不要加L
2011-6-27 15:31
0
雪    币: 143
活跃值: (61)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
15
n楼上好像说反了。
楼主应该是把ansi当unicode看待了。
2011-6-27 15:34
0
雪    币: 9
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
我把这个函数的代码发给你,直接调用就行了

VOID WriteFileTest()
{
        OBJECT_ATTRIBUTES objectAttributes;
        IO_STATUS_BLOCK iostatus;
        HANDLE hfile;
        UNICODE_STRING logFileUnicodeString;
        UNICODE_STRING test;
        RtlInitUnicodeString( &test,
                L"我是jsjscool");
        //初始化UNICODE_STRING字符串
        RtlInitUnicodeString( &logFileUnicodeString,
                L"\\??\\C:\\text.txt");

        //初始化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

        PWCHAR pBuffer = (PWCHAR)ExAllocatePool(PagedPool,BUFFER_SIZE);
        //构造要填充的数据
        RtlFillMemory(pBuffer,BUFFER_SIZE,0xD0DC);
        RtlCopyMemory(pBuffer,test.Buffer, test.Length);
        KdPrint(("The program will write %d bytes\n",BUFFER_SIZE));
        //引用楼上写文件方法
        ZwWriteFile(hfile,NULL,NULL,NULL,&iostatus,L"我是jsjscool",20,NULL,NULL);
        KdPrint(("The program really wrote %d bytes\n",iostatus.Information));

        //构造要填充的数据
        RtlFillMemory(pBuffer,BUFFER_SIZE,0x55B5);

        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);
}
2011-6-27 15:39
0
雪    币: 9
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
嗯!这样就可以写入中文了,能给我解释为什么吗?
书上对L的定义是——在构造字符串的时候使用一个关键字“L”,编译器会自动生成所需要的宽字符。(摘自:windows驱动开发技术详解)
2011-6-27 15:48
0
雪    币: 4817
活跃值: (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
你把代码里的ZwWriteFile(hfile,NULL,NULL,NULL,&iostatus,pBuffer,BUFFER_SIZE,&number,NULL);
去掉试试,就能看到中文了。

因为 ZwWriteFile(hfile,NULL,NULL,NULL,&iostatus,L"我是jsjscool",20,NULL,NULL);输出的是UNICODE编码,一般来讲,记事本保存UNICODE编码会在最前面加入FFFE标识,打开的时候如果记事本看到这个标识,就按照UNICODE解析,如果没看到,会做其他判断,如果你把后面的ZwWriteFile去掉,那么写入文件的就全部都是UNICODE编码,记事本就会认为是UNICODE编码并显示出来,如果后边的ZwWriteFile没去掉,写进一些其他字符,影响到记事本就判断,就会显示乱码,这个时候你可以在文件前加入FFFE标识,记事本就会直接按照UNICODE编码显示出来。

至于前面的什么ANSI当UNICODE看或者UNICODE当ANSI,其实都不是关键,关键是记事本解析方式,你写进文件是ANSI还是UNICODE总得告诉记事本吧,记事本又不是万能的,只要告诉记事本文件的编码方式,不管是ANSI或UNICODE,都是可以正常显示的。
2011-6-27 16:19
0
游客
登录 | 注册 方可回帖
返回
//