-
-
东拼西凑认识WDM驱动程序
-
发表于: 2008-1-3 22:01 5120
-
原文引自:
262K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6h3y4G2k6r3g2H3M7X3!0B7k6h3y4@1i4K6u0W2j5$3!0E0i4K6u0r3d9@1u0Q4x3V1k6K6P5i4y4@1k6h3#2Q4x3V1k6i4c8p5#2Q4y4h3k6p5M7X3W2$3k6i4u0Q4y4h3k6V1k6i4k6W2L8r3!0H3L8h3g2F1N6q4)9J5k6h3q4K6M7s2R3`.
部分注释来自:
Programming the Microsoft Windows Driver Model.pdf
建立你自己的WDM驱动:
所需重要的数据结构:DEVICE_EXTENSION!

对上图的一些解释:
1.对于 WDM 驱动程序的DriverEntry 例程,其主要工作是把各种函数指针填入驱动程序对象。这些指针为操作系统指明了驱动程序容器中各种子例程的位置。
2.需要对 IRP排队的驱动程序一般都有一个StartIo例程。执行 DMA传输的驱动程序应有一个 AdapterControl 例程。大部分能生成硬件中断的设备,其驱动程序都有一个中断服务例程(ISR)和一个推迟过程调用(DPC)例程。驱动程序一般都有几个支持不同类型IRP的派遣函数,其中三个派遣函数(DispatchPnp,DispatchPower,DispatchWmi)是必须的。所以,WDM 驱动程序开发者的一个任务就是为这个容器选择所需要的例程。
DriverEntry 注册所有的例程:
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
RtlInitUnicodeString(
&Global_sz_Drv_RegInfo,
RegistryPath->Buffer);
// Initialize function pointers
DriverObject->DriverUnload = DriverUnload;
DriverObject->DriverExtension->AddDevice = AddDevice;
DriverObject->MajorFunction[IRP_MJ_CREATE] = PsdoDispatchCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = PsdoDispatchClose;
DriverObject->MajorFunction[IRP_MJ_READ] = PsdoDispatchRead;
DriverObject->MajorFunction[IRP_MJ_WRITE] = PsdoDispatchWrite;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PsdoDispatchDeviceControl;
DriverObject->MajorFunction[IRP_MJ_POWER] = PsdoDispatchPower;
DriverObject->MajorFunction[IRP_MJ_PNP] = PsdoDispatchPnP;
return STATUS_SUCCESS;
}

对上图的一些解释:
1.WDM驱动程序的 DriverEntry 例程应完成对这个驱动程序对象的初始化并返回。
2.PnP管理器按照设备驱动程序的要求构造了设备对象堆栈,PnP管理器自动把新硬件匹配到正确的 WDM 驱动程序上,并调用该驱动程序的 AddDevice 例程,再由AddDevice 例程做所有必要的初始化工作。
3.在 WDM 驱动程序模型中,每个硬件设备至少有两个驱动程序。
a.其中一个驱动程序我们称为功能(function)驱动程序,通常它就是你认为的那个硬件设备驱动程序。它了解使硬件工作的所有细节,负责初始化 I/O 操作,有责任处理 I/O 操作完成时所带来的中断事件,有责任为用户提供一种设备适合的控制方式。
b.另一个驱动程序我们称为总线(bus)驱动程序。它负责管理硬件与计算机的连接。
c.有些设备有两个以上的驱动程序。我们使用术语过滤器驱动程序(filter driver)来描述它们。某些过滤器驱动程序,仅仅是在功能驱动程序执行I/O 操作时进行监视。
AddDevice 创建一个设备对象并把它连接到已存在的设备堆栈中。

通常,你将使用CreateFile/fopen函数连接底层设备,Win32子系统发送IRP_MJ_CREATE,
并向驱动程序请求连接目标设备。

你将使用CloseFile/flose函数连接底层设备,Win32子系统发送IRP_MJ_CREATE,
并向驱动程序请求关闭目标设备。
262K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6h3y4G2k6r3g2H3M7X3!0B7k6h3y4@1i4K6u0W2j5$3!0E0i4K6u0r3d9@1u0Q4x3V1k6K6P5i4y4@1k6h3#2Q4x3V1k6i4c8p5#2Q4y4h3k6p5M7X3W2$3k6i4u0Q4y4h3k6V1k6i4k6W2L8r3!0H3L8h3g2F1N6q4)9J5k6h3q4K6M7s2R3`.
部分注释来自:
Programming the Microsoft Windows Driver Model.pdf
建立你自己的WDM驱动:
所需重要的数据结构:DEVICE_EXTENSION!
- typedef struct tagDEVICE_EXTENSION {
PDEVICE_OBJECT DeviceObject; // device object this driver creates
PDEVICE_OBJECT NextDeviceObject; // next-layered device object in this
// device stack
DEVICE_CAPABILITIES pdc; // device capability
IO_REMOVE_LOCK RemoveLock; // removal control locking structure
LONG handles; // # open handles
PVOID DataBuffer; // Internal Buffer for Read/Write I/O
UNICODE_STRING Device_Description; // Device Description
SYSTEM_POWER_STATE SysPwrState; // Current System Power State
DEVICE_POWER_STATE DevPwrState; // Current Device Power State
PIRP PowerIrp; // Current Handling Power-Related IRP
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

对上图的一些解释:
1.对于 WDM 驱动程序的DriverEntry 例程,其主要工作是把各种函数指针填入驱动程序对象。这些指针为操作系统指明了驱动程序容器中各种子例程的位置。
2.需要对 IRP排队的驱动程序一般都有一个StartIo例程。执行 DMA传输的驱动程序应有一个 AdapterControl 例程。大部分能生成硬件中断的设备,其驱动程序都有一个中断服务例程(ISR)和一个推迟过程调用(DPC)例程。驱动程序一般都有几个支持不同类型IRP的派遣函数,其中三个派遣函数(DispatchPnp,DispatchPower,DispatchWmi)是必须的。所以,WDM 驱动程序开发者的一个任务就是为这个容器选择所需要的例程。
DriverEntry 注册所有的例程:
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
RtlInitUnicodeString(
&Global_sz_Drv_RegInfo,
RegistryPath->Buffer);
// Initialize function pointers
DriverObject->DriverUnload = DriverUnload;
DriverObject->DriverExtension->AddDevice = AddDevice;
DriverObject->MajorFunction[IRP_MJ_CREATE] = PsdoDispatchCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = PsdoDispatchClose;
DriverObject->MajorFunction[IRP_MJ_READ] = PsdoDispatchRead;
DriverObject->MajorFunction[IRP_MJ_WRITE] = PsdoDispatchWrite;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PsdoDispatchDeviceControl;
DriverObject->MajorFunction[IRP_MJ_POWER] = PsdoDispatchPower;
DriverObject->MajorFunction[IRP_MJ_PNP] = PsdoDispatchPnP;
return STATUS_SUCCESS;
}

对上图的一些解释:
1.WDM驱动程序的 DriverEntry 例程应完成对这个驱动程序对象的初始化并返回。
2.PnP管理器按照设备驱动程序的要求构造了设备对象堆栈,PnP管理器自动把新硬件匹配到正确的 WDM 驱动程序上,并调用该驱动程序的 AddDevice 例程,再由AddDevice 例程做所有必要的初始化工作。
3.在 WDM 驱动程序模型中,每个硬件设备至少有两个驱动程序。
a.其中一个驱动程序我们称为功能(function)驱动程序,通常它就是你认为的那个硬件设备驱动程序。它了解使硬件工作的所有细节,负责初始化 I/O 操作,有责任处理 I/O 操作完成时所带来的中断事件,有责任为用户提供一种设备适合的控制方式。
b.另一个驱动程序我们称为总线(bus)驱动程序。它负责管理硬件与计算机的连接。
c.有些设备有两个以上的驱动程序。我们使用术语过滤器驱动程序(filter driver)来描述它们。某些过滤器驱动程序,仅仅是在功能驱动程序执行I/O 操作时进行监视。
AddDevice 创建一个设备对象并把它连接到已存在的设备堆栈中。
- NTSTATUS
AddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
)
{
ULONG DeviceExtensionSize;
PDEVICE_EXTENSION p_DVCEXT;
PDEVICE_OBJECT ptr_PDO;
NTSTATUS status;
RtlInitUnicodeString(
&Global_sz_DeviceName, L"");
//Get DEVICE_EXTENSION required memory space
DeviceExtensionSize = sizeof(DEVICE_EXTENSION);
//Create Device Object
status = IoCreateDevice(
DriverObject,
DeviceExtensionSize,
&Global_sz_DeviceName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&ptr_PDO
);
if (NT_SUCCESS(status)) {
ptr_PDO->Flags &= ~DO_DEVICE_INITIALIZING;
ptr_PDO->Flags |= DO_BUFFERED_IO; //For Buffered I/O
//ptr_PDO->Flags |= DO_DIRECT_IO; //For Direct I/O
p_DVCEXT = ptr_PDO->DeviceExtension;
p_DVCEXT->DeviceObject = ptr_PDO;
RtlInitUnicodeString(
//Other initialization tasks go here
//Store next-layered device object
//Attach device object to device stack
p_DVCEXT->NextDeviceObject =
IoAttachDeviceToDeviceStack(ptr_PDO, PhysicalDeviceObject);
}
return status;
}

通常,你将使用CreateFile/fopen函数连接底层设备,Win32子系统发送IRP_MJ_CREATE,
并向驱动程序请求连接目标设备。
- NTSTATUS
PsdoDispatchCreate(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PIO_STACK_LOCATION p_IO_STK;
PDEVICE_EXTENSION p_DVCEXT;
NTSTATUS status;
p_IO_STK = IoGetCurrentIrpStackLocation(Irp);
p_DVCEXT = DeviceObject->DeviceExtension;
status = IoAcquireRemoveLock(&p_DVCEXT->RemoveLock, p_IO_STK->FileObject);
if (NT_SUCCESS(status)) {
CompleteRequest(Irp, STATUS_SUCCESS, 0);
return STATUS_SUCCESS;
} else {
IoReleaseRemoveLock(&p_DVCEXT->RemoveLock, p_IO_STK->FileObject);
CompleteRequest(Irp, status, 0);
return status;
}
}

你将使用CloseFile/flose函数连接底层设备,Win32子系统发送IRP_MJ_CREATE,
并向驱动程序请求关闭目标设备。
- NTSTATUS
PsdoDispatchClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PIO_STACK_LOCATION p_IO_STK;
PDEVICE_EXTENSION p_DVCEXT;
p_IO_STK = IoGetCurrentIrpStackLocation(Irp);
p_DVCEXT = DeviceObject->DeviceExtension;
IoReleaseRemoveLock(&p_DVCEXT->RemoveLock,
p_IO_STK->FileObject);
CompleteRequest(Irp, STATUS_SUCCESS, 0);
return STATUS_SUCCESS;
}
赞赏
他的文章
- 出售二手驱动、内核、漏洞、加密解密等编程书籍 4455
- [原创]python获取QQ空间前100篇blog的地址和标题的方法 8351
- [求助]翻译求助 5054
- [原创]对PeCompact 2.x--IAT加密壳详解 7063
- [原创]简单的堆栈平衡原理脚本 5251
谁下载
kanxue
forgot
FishSeeWater
nig
wzmooo
ylp1332
PowerBoy
cd37ycs
kore
zzlxp
JiYangTX
Xacs
mickeylan
coolbye
warcraft
nuller
执着我一生
ww990
天涯浪人
z123z123
a3xx
北极星2003
morning
linyangcan
猪头三
zhuwg
Aker
jijimao
foria
qqeleven
tobybird
qandzjl
hnzz
zhujian
sislcb
vodka
hawking
小陶人
渗透
Cycasst
asd
liuzewei
jinghua
xszhou
basketwill
cham
girl
drwch
火影
魔月
xoojo
zhoujiamur
jingru
esun
hackersea
haifengjl
wping
foxxp
feezd
stdafx
sudami
joewy
cxbxy
scship
ainwx
阳小子
hacklove
eversoft
要学会编
stu
goushixiun
helpmsg
Jeller
vbcs
lttttt
carche
紫色的魚
yingyue
sanfang
combojiang
ccgto
成松林
loien
YiTim
cowboylyh
inerir
lslsyqyq
chinaruto
zhtjia
yangras
ExcSpirit
avbcad
qianxichao
loudy
szdbg
CCDeath
tonybo
rengood
gtime
谁下载
kanxue
forgot
FishSeeWater
nig
wzmooo
ylp1332
PowerBoy
cd37ycs
kore
zzlxp
JiYangTX
Xacs
mickeylan
coolbye
warcraft
nuller
执着我一生
ww990
天涯浪人
z123z123
a3xx
北极星2003
morning
linyangcan
猪头三
zhuwg
Aker
jijimao
foria
qqeleven
tobybird
qandzjl
hnzz
zhujian
sislcb
vodka
hawking
小陶人
渗透
Cycasst
asd
liuzewei
jinghua
xszhou
basketwill
cham
girl
drwch
火影
魔月
xoojo
zhoujiamur
jingru
esun
hackersea
haifengjl
wping
foxxp
feezd
stdafx
sudami
joewy
cxbxy
scship
ainwx
阳小子
hacklove
eversoft
要学会编
stu
goushixiun
helpmsg
Jeller
vbcs
lttttt
carche
紫色的魚
yingyue
sanfang
combojiang
ccgto
成松林
loien
YiTim
cowboylyh
inerir
lslsyqyq
chinaruto
zhtjia
yangras
ExcSpirit
avbcad
qianxichao
loudy
szdbg
CCDeath
tonybo
rengood
gtime
谁下载
kanxue
forgot
FishSeeWater
nig
wzmooo
ylp1332
cd37ycs
kore
zzlxp
JiYangTX
Xacs
mickeylan
coolbye
warcraft
nuller
执着我一生
ww990
天涯浪人
z123z123
a3xx
北极星2003
morning
linyangcan
猪头三
zhuwg
Aker
jijimao
foria
qqeleven
tobybird
qandzjl
hnzz
zhujian
sislcb
vodka
hawking
小陶人
渗透
Cycasst
asd
liuzewei
jinghua
xszhou
basketwill
cham
girl
drwch
火影
魔月
xoojo
zhoujiamur
jingru
esun
hackersea
haifengjl
wping
foxxp
feezd
stdafx
sudami
joewy
cxbxy
scship
ainwx
阳小子
hacklove
eversoft
要学会编
stu
goushixiun
helpmsg
Jeller
vbcs
lttttt
carche
紫色的魚
yingyue
sanfang
combojiang
ccgto
成松林
loien
YiTim
cowboylyh
inerir
lslsyqyq
chinaruto
zhtjia
yangras
ExcSpirit
avbcad
qianxichao
loudy
szdbg
CCDeath
tonybo
rengood
gtime
lly鹅
谁下载
kanxue
forgot
FishSeeWater
nig
wzmooo
ylp1332
PowerBoy
cd37ycs
kore
zzlxp
JiYangTX
Xacs
mickeylan
coolbye
warcraft
nuller
执着我一生
ww990
天涯浪人
z123z123
a3xx
北极星2003
morning
linyangcan
猪头三
zhuwg
Aker
jijimao
foria
qqeleven
tobybird
qandzjl
hnzz
zhujian
sislcb
vodka
hawking
小陶人
渗透
Cycasst
asd
liuzewei
jinghua
xszhou
basketwill
cham
girl
drwch
火影
魔月
xoojo
zhoujiamur
jingru
esun
hackersea
haifengjl
wping
foxxp
feezd
stdafx
sudami
joewy
cxbxy
scship
ainwx
阳小子
hacklove
eversoft
要学会编
stu
goushixiun
helpmsg
Jeller
vbcs
lttttt
carche
紫色的魚
yingyue
sanfang
combojiang
ccgto
成松林
loien
YiTim
cowboylyh
inerir
lslsyqyq
chinaruto
zhtjia
yangras
ExcSpirit
avbcad
qianxichao
loudy
szdbg
CCDeath
tonybo
rengood
gtime
赞赏
雪币:
留言: