aqian88888888
驱动牛犊
驱动牛犊
  • 注册日期2002-05-31
  • 最后登录2004-05-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1710回复:13

参数的传递问题

楼主#
更多 发布于:2002-06-07 09:51
函数ReadFile、WriteFile和DeviceIoControl的参数是怎么传给驱动程序,还有驱动程序是怎样把一些参数传给这些函数的?
兄弟们有资料的话,贴出来看看!MSDN提示出外:)

最新喜欢:

ameiamei
zydcat
驱动老牛
驱动老牛
  • 注册日期2001-12-06
  • 最后登录2006-04-12
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-06-07 09:55
这是最基本的东西,你还是先看看书吧,然后再看代码
[color=red]肥虫虫[/color] [img]http://www.driverdevelop.com/forum/upload/bradley/2002-11-15_ig01.gif[/img]
aqian88888888
驱动牛犊
驱动牛犊
  • 注册日期2002-05-31
  • 最后登录2004-05-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-06-07 11:11
书上讲的不详细,看不懂我才问的;
指条路吧!
aqian88888888
驱动牛犊
驱动牛犊
  • 注册日期2002-05-31
  • 最后登录2004-05-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-06-07 11:16
比如说我要把一个端口号从writefile函数和readfile函数中传到驱动程序中去,该怎么办?
zydcat
驱动老牛
驱动老牛
  • 注册日期2001-12-06
  • 最后登录2006-04-12
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-06-07 11:36
你看一下函数原型就明白
[color=red]肥虫虫[/color] [img]http://www.driverdevelop.com/forum/upload/bradley/2002-11-15_ig01.gif[/img]
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
5楼#
发布于:2002-06-07 11:52
faint!!!!!!!! :mad:
Tom.Cat
禁止发言
禁止发言
  • 注册日期2001-10-10
  • 最后登录2019-07-29
  • 粉丝1
  • 关注0
  • 积分-53792分
  • 威望197411点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
  • 社区居民
6楼#
发布于:2002-06-07 17:28
用户被禁言,该主题自动屏蔽!
aqian88888888
驱动牛犊
驱动牛犊
  • 注册日期2002-05-31
  • 最后登录2004-05-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-06-07 18:59
有啊,可是我不知道他是怎么传到驱动程序里面去的啊?
还有驱动程序里面怎么用他啊?
请指点一下,大侠:)bow
magicx
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2014-08-18
  • 粉丝1
  • 关注0
  • 积分-14分
  • 威望13点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2002-06-07 23:33

基本概念性问题。。。。。。。。

aqian88888888兄: 你“懒”的可以。 ;)

我只讲大概的,具体的建议你看书。。。。。(基本的)

如WriteFile:
BOOL WriteFile(
  HANDLE hFile,                    // handle to file to write to
  LPCVOID lpBuffer,                // pointer to data to write to file
  DWORD nNumberOfBytesToWrite,     // number of bytes to write
  LPDWORD lpNumberOfBytesWritten,  // pointer to number of bytes written
  LPOVERLAPPED lpOverlapped        // pointer to structure for overlapped I/O
);
第一项为目标驱动的相关的句柄,要先CreateFile之来得到,再为输入输出区等。

当你向特定的驱动操作是,IO管理器(如在win2k中)会根据第一项的句柄,找到该驱动程序,后将相关的参数(相应处理后)传给该驱动程序。

反之由驱动---IO管理器--- 你的函数。。。

以上只是“大概”。

你找一下,相关的书上都有。。。。。。

你“懒”的是够可以。 ;)


[color=red]大头鬼! :P[/color]
aqian88888888
驱动牛犊
驱动牛犊
  • 注册日期2002-05-31
  • 最后登录2004-05-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2002-06-08 10:47

我只讲大概的,具体的建议你看书。。。。。(基本的)

如WriteFile:
BOOL WriteFile(
  HANDLE hFile,                    // handle to file to write to
  LPCVOID lpBuffer,                // pointer to data to write to file
  DWORD nNumberOfBytesToWrite,     // number of bytes to write
  LPDWORD lpNumberOfBytesWritten,  // pointer to number of bytes written
  LPOVERLAPPED lpOverlapped        // pointer to structure for overlapped I/O
);
第一项为目标驱动的相关的句柄,要先CreateFile之来得到,再为输入输出区等。

当你向特定的驱动操作是,IO管理器(如在win2k中)会根据第一项的句柄,找到该驱动程序,后将相关的参数(相应处理后)传给该驱动程序。

反之由驱动---IO管理器--- 你的函数。。。


    兄弟,说句实在话,你说的我都明白,如果这个都不明白,我就不敢来这儿混了,关键是细节问题我不明白啊!中国人写书也都是概论、概述什么的,再说,我现在是急啊,不知道该去哪里找啊,唉!兄弟们说得是,我去翻书,争取成为书虫
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2002-06-08 11:38
哦,开始以为你是来问ReadFile是怎么用的,原来不是,hehe
以ReadFile为例简单说说:
1、首先讲讲系统服务:
你调用Win32API(如ReadFile)很多(包括ReadFile)会转入native API,对ReadFile是

NtReadFile(ZwReadFile):

:u ZwReadFile
ntdll!ZwReadFile
001B:77F7EF23 MOV EAX,000000B7
001B:77F7EF28 MOV EDX,7FFE0300
001B:77F7EF2D CALL EDX
001B:77F7EF2F RET 0024
001B:77F7EF32 NOP

:u7FFE0300
001B:7FFE0300 MOV EDX,ESP
001B:7FFE0302 SYSENTER         ;goto os kernel
001B:7FFE0304 RET
001B:7FFE0305 PUSHFD
001B:7FFE0306 OR DWORD PTR [ESP],00000100
001B:7FFE030D POPFD
001B:7FFE030E RET
001B:7FFE030F MOV EDX,ESP
:g


上面是对XP而言,对2000,一般用的是INT2Eh:
mov eax,000000A1
lea edx,dword ptr[esp+04]
int 2e
ret 0024

系统经sysenter或int2eh进入了ring0,此后系统会分派你的服务,下面仍是XP上的代码,做

了简单注释:
:u 804D4DCD L 200
0008:804D4DCD PUSH 00
0008:804D4DCF PUSH EBP
0008:804D4DD0 PUSH EBX
0008:804D4DD1 PUSH ESI
0008:804D4DD2 PUSH EDI
0008:804D4DD3 PUSH FS
0008:804D4DD5 MOV EBX,00000030
0008:804D4DDA MOV FS,BX
0008:804D4DDD PUSH DWORD PTR [FFDFF000]
0008:804D4DE3 MOV DWORD PTR [FFDFF000],FFFFFFFF
0008:804D4DED MOV ESI,[FFDFF124]
ETHREAD=>ESI

0008:804D4DF3 PUSH DWORD PTR [ESI+00000140]
0008:804D4DF9 SUB ESP,48
0008:804D4DFC MOV EBX,[ESP+6C]
byte ptr[ESP+6C]=08

0008:804D4E00 AND EBX,01
0008:804D4E03 MOV [ESI+00000140],BL
BL(0)=>ETHREAD.PreviousMode

0008:804D4E09 MOV EBP,ESP
0008:804D4E0B MOV EBX,[ESI+00000134]
old ETHREAD.TrapFrame=>EBX

0008:804D4E11 MOV [EBP+3C],EBX
0008:804D4E14 MOV [ESI+00000134],EBP
0008:804D4E1A CLD
0008:804D4E1B TEST BYTE PTR [ESI+2C],FF
debug flag is active?

0008:804D4E1F JNZ 804D4CEC
0008:804D4E25 STI
0008:804D4E26 MOV EDI,EAX
0008:804D4E28 SHR EDI,08
0008:804D4E2B AND EDI,30
0008:804D4E2E MOV ECX,EDI
0008:804D4E30 ADD EDI,[ESI+000000E0]
get ServiceTable

0008:804D4E36 MOV EBX,EAX
0008:804D4E38 AND EAX,00000FFF
0008:804D4E3D CMP EAX,[EDI+08]
correct ServiceId?

0008:804D4E40 JAE 804D4CA2
0008:804D4E46 CMP ECX,10
extended Service?

0008:804D4E49 JNZ 804D4E65
0008:804D4E4B MOV ECX,[FFDFF018]
0008:804D4E51 XOR EBX,EBX
0008:804D4E53 OR EBX,[ECX+00000F70]
0008:804D4E59 JZ 804D4E65
0008:804D4E5B PUSH EDX
0008:804D4E5C PUSH EAX
0008:804D4E5D CALL [80544C44]
0008:804D4E63 POP EAX
0008:804D4E64 POP EDX
0008:804D4E65 INC DWORD PTR [FFDFF638]
0008:804D4E6B MOV ESI,EDX
0008:804D4E6D MOV EBX,[EDI+0C]
0008:804D4E70 XOR ECX,ECX
0008:804D4E72 MOV CL,[EBX+EAX]
get bytes of parameters   //*****************

0008:804D4E75 MOV EDI,[EDI]
0008:804D4E77 MOV EBX,[EAX*4+EDI]
get the service function address  //****************

0008:804D4E7A SUB ESP,ECX
0008:804D4E7C SHR ECX,02
0008:804D4E7F MOV EDI,ESP
0008:804D4E81 CMP ESI,[ntoskrnl!MmUserProbeAddress]
0008:804D4E87 JAE 804D5033
do something if ... from ring0

0008:804D4E8D REPZ MOVSD
copy parameters  //******************

0008:804D4E8F CALL EBX
call service function   //********************

0008:804D4E91 MOV ESP,EBP
0008:804D4E93 MOV ECX,[FFDFF124]
0008:804D4E99 MOV EDX,[EBP+3C]
0008:804D4E9C MOV [ECX+00000134],EDX
0008:804D4EA2 CLI
0008:804D4EA3 TEST DWORD PTR [EBP+70],00020000
v86 mode?

0008:804D4EAA JNZ 804D4EB2
0008:804D4EAC TEST BYTE PTR [EBP+6C],01
ring0 or ring3?

0008:804D4EB0 JZ 804D4F08
0008:804D4EB2 MOV EBX,[FFDFF124]
0008:804D4EB8 MOV BYTE PTR [EBX+2E],00
0008:804D4EBC CMP BYTE PTR [EBX+4A],00
ContextSwitches?

0008:804D4EC0 JZ 804D4F08
0008:804D4EC2 MOV EBX,EBP
0008:804D4EC4 MOV [EBX+44],EAX
0008:804D4EC7 MOV DWORD PTR [EBX+50],0000003B
0008:804D4ECE MOV DWORD PTR [EBX+38],00000023
0008:804D4ED5 MOV DWORD PTR [EBX+34],00000023
0008:804D4EDC MOV DWORD PTR [EBX+30],00000000
0008:804D4EE3 MOV ECX,00000001
0008:804D4EE8 CALL [HAL!KfRaiseIrql]
0008:804D4EEE PUSH EAX
0008:804D4EEF STI
0008:804D4EF0 PUSH EBX
0008:804D4EF1 PUSH 00
0008:804D4EF3 PUSH 01
0008:804D4EF5 CALL ntoskrnl!KiDeliverApc
0008:804D4EFA POP ECX
0008:804D4EFB CALL [HAL!KfLowerIrql]
0008:804D4F01 MOV EAX,[EBX+44]
0008:804D4F04 CLI
0008:804D4F05 JMP 804D4EB2
0008:804D4F07 NOP

go on
0008:804D4F08 MOV EDX,[ESP+4C]
0008:804D4F0C MOV EBX,FS:[00000050]
0008:804D4F13 MOV FS:[00000000],EDX
0008:804D4F1A MOV ECX,[ESP+48]
0008:804D4F1E MOV ESI,FS:[00000124]
0008:804D4F25 MOV [ESI+00000140],CL
0008:804D4F2B TEST EBX,0000000F
0008:804D4F31 JNZ 804D4FA8
0008:804D4F33 TEST DWORD PTR [ESP+70],00020000
0008:804D4F3B JNZ 804D57EA
0008:804D4F41 TEST WORD PTR [ESP+6C],FFF8
0008:804D4F48 JZ 804D5001
0008:804D4F4E CMP WORD PTR [ESP+6C],1B
0008:804D4F54 BT DWORD PTR [ESP+6C],00
0008:804D4F5B CMC
0008:804D4F5C JA 804D4FEF ;if(DT!=1B&DREAD.PreviousMode==UserMode) error;
0008:804D4F62 CMP WORD PTR [EBP+6C],08
0008:804D4F67 JZ 804D4F6E
0008:804D4F69 LEA ESP,[EBP+50]
0008:804D4F6C POP FS
0008:804D4F6E LEA ESP,[EBP+54]
0008:804D4F71 POP EDI
0008:804D4F72 POP ESI
0008:804D4F73 POP EBX
0008:804D4F74 POP EBP
0008:804D4F75 CMP WORD PTR [ESP+08],0080
0008:804D4F7C JA 804D5806
0008:804D4F82 ADD ESP,04
0008:804D4F85 TEST DWORD PTR [ESP+04],00000001
0008:804D4F8D JNZ 804D4F95
0008:804D4F8F POP EDX
0008:804D4F90 POP ECX
0008:804D4F91 POPFD
0008:804D4F92 JMP EDX
return to ring0 (edx=>eip)
0008:804D4F94 IRETD

0008:804D4F95 POP EDX
0008:804D4F96 ADD ESP,08
0008:804D4F99 POP ECX
0008:804D4F9A STI
0008:804D4F9B SYSEXIT
return to ring3 (edx=>eip,ecx=>esp)

0008:804D4F9D POP ECX
0008:804D4F9E ADD ESP,08
0008:804D4FA1 POP ESP
0008:804D4FA2 SYSRET
?\"SYSRET\"?? machine code is?
0008:804D4FA4 IRETD
0008:804D4FA5 LEA ECX,[ECX+00]
0008:804D4FA8 TEST DWORD PTR [EBP+70],00020000
0008:804D4FAF JNZ 804D4FBE
0008:804D4FB1 TEST DWORD PTR [EBP+6C],00000001
0008:804D4FB8 JZ 804D4F33
0008:804D4FBE MOV EBX,00000000
0008:804D4FC3 MOV ESI,[EBP+18]
0008:804D4FC6 MOV EDI,[EBP+1C]
0008:804D4FC9 MOV DR7,EBX
0008:804D4FCC MOV DR0,ESI
: g

看打了“**********”的几行,它们copy用户参数进内核空间(由SSPT得大小,这里的参数

是HANDLE hFile,LPVOID lpBuffer,DWORD nNumberOfBytesToRead,LPDWORD

lpNumberOfBytesRead,LPOVERLAPPED lpOverlapped),并调用内核服务(由SSDT得地址)。

2、I/O管理器:
这部分很多书(比如InsideWindows2000)都有讲到,不多说了。I/O管理器根据具体的缓冲

策略操作并发送IRP,或分配了缓冲、等驱动写好了再copy至lpBuffer所指;或直接I/O。。



随后就返回应用程序了(当然可能服务早就返回了:异步IO)。
apmusb
游客
游客
11楼#
发布于:2002-06-08 11:41
看这本书――Jeffrey Richter的《Windows高级编程指南》
magicx
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2014-08-18
  • 粉丝1
  • 关注0
  • 积分-14分
  • 威望13点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2002-06-08 17:18
[quote]
我只讲大概的,具体的建议你看书。。。。。(基本的)

如WriteFile:
BOOL WriteFile(
  HANDLE hFile,                    // handle to file to write to
  LPCVOID lpBuffer,                // pointer to data to write to file
  DWORD nNumberOfBytesToWrite,     // number of bytes to write
  LPDWORD lpNumberOfBytesWritten,  // pointer to number of bytes written
  LPOVERLAPPED lpOverlapped        // pointer to structure for overlapped I/O
);
第一项为目标驱动的相关的句柄,要先CreateFile之来得到,再为输入输出区等。

当你向特定的驱动操作是,IO管理器(如在win2k中)会根据第一项的句柄,找到该驱动程序,后将相关的参数(相应处理后)传给该驱动程序。

反之由驱动---IO管理器--- 你的函数。。。


    兄弟,说句实在话,你说的我都明白,如果这个都不明白,我就不敢来这儿混了,关键是细节问题我不明白啊!中国人写书也都是概论、概述什么的,再说,我现在是急啊,不知道该去哪里找啊,唉!兄弟们说得是,我去翻书,争取成为书虫
 [/quote]

嘿嘿,见笑,见笑。。。。。。。。。。

 :)
[color=red]大头鬼! :P[/color]
leaf
驱动牛犊
驱动牛犊
  • 注册日期2002-05-21
  • 最后登录2004-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2002-06-08 17:48
read
应用:
ReadFile:
lpBuffer,nNumberOfBytesToRead,lpNumberOfBytesRead
驱动:
IRP_MJ_READ:
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
IrpStack->Parameters.Read.ByteOffset.QuadPart:文件指针,可以使用Seek设定,不过好象有的不支持.
IrpStack->Parameters.Read.Length:nNumberOfBytesToRead
Irp->AssociatedIrp.SystemBuffer:lpBuffer
Irp->IoStatus.Information:lpNumberOfBytesRead

写和IoControl也基本类似.
游客

返回顶部