一.驱动程序介绍
Windows 环境下,应用程序访问硬件设备需要通过设备驱动程序。
在Windows 95/98下,驱动程序通常是一个Vxd文件;而在Windows NT下,
驱动程序则是一个Sys文件。虽然这两个操作系统都是出自微软门下,
但其使用的驱动程序结构是完全不同的,因此当一个硬件产品需要在以
上两种操作系统下都能运行时,就需要分别编写其特定环境下的驱驱
动程序。驱动程序的编写是一件相当复杂的工作。编程者首先要学习
95/98/NT操作系统的内部工作机制,当对其内部工作机制有了相当了
解后,接下来就要学习如何编写设备驱动程序,当真正要开始编驱动
程序的时候,还要学会如何在Windows内核模式下调试程序,在这里有
一点要说明的是Windows的内核模式可不比用户模式那么简单,在内核
模式下调试程序需要借助SoftICE之类的调试工具。经过不懈努力编写
好驱动程序后,就可以编写应用软件了,这些应用软件就是我们现在
看得见摸得着的东西了,比如Windows 右下角的那个音量控制图标,
它就是一个应用软件,在它下面其实还要经过声卡的驱动程序才能控
制音量的大小。总地来说编写驱动程序是一件复杂的工作,需要编写
者耐心;而学习编写驱动程序也会有一个曲折的过程,需要学习者有
恒心和毅力,在此我也要鼓励那此刚开始学驱动程序编程的初学者。
二.NT和WDM设备驱动程序开发书评
1. The Windows NT Device Driver Book(Art Baker)
- 中译本 :Windows NT设备驱动程序设计指南(机械工业出版社)
这是所出版的第一本关于NT driver开发的书,它只讨论了NT4.0的设备驱动程序开发,Ba
ker先生现在正从事此书第二版的写作.本书只覆盖了部份NT driver(如基本PIO和DMA)的
开发,且叙述得不够深入.如果你想写PCI Drivers的话,你从本书得不到帮助.
本书的最大缺点是技术错误太多!,寄希望于它的第二版吧!
2.Windows NT Device Driver Development by Peter Viscarola and W.Anthony Maso
n(Macmillan出版社)
-中译本:无
该书于1998年10月出版,它同样是只讨论了NT4.0的设备驱动程序开发,本书提供了许多N
T OS和I/O子系统的系统结构细节.另外,本书的两位作者基于自己在实际开发过程中所积
累的经验,在书中提出了很多开发drivers的技巧和建议.此书没有告诉读者"你为什么要
这么作",而只是解释了如何作以及用什么工具去实现.该书相当深入地阐述了各种不同的
drivers的开发,如DMA和PIO.本书从技术的角度讲,是写得比较精确的!
3.Developing Windows NT Devices Drivers byEdwardN.Dekker and Joseph M.Newcom
er(Addison出版社)
-中译本:无
本书是一本Drivers开发的百科全书,值得买!,主要还是讨论NT4.0的设备驱动程序开发.
此书提供了大量硬件的技术细节,如PCI/ISA总线.本书在教你如何写drivers的同时,还提
供了许多示范代码.
本书比较精确.读本书可分享作者丰富的drivers开发经验,很明显,作者很精通drivers的
开发,也知道如何解释这些问题.另外,本书的排版和写作风格也相当不错!
4.Writng Windows WDM Decvice Drivers by Chris Cant(R&D Books)
-中译本:WDM编程指南,刚出版.
不明白为什么国内要选这本书来翻译出版?,本书主要讨论WDM的开发.如果你想看到设备
/硬件信息或OS的系统结构,还是另找它书吧!我想本书的书名取为"WDM入门教程"也许更
为合适.本书只花了两页的功夫来讨论DMA.有时用词也不是那么恰当和精确. 如果你是W
in32程序员或技术经理,或许本书有点用.如果你想知道如何去写一个真正的drivers的话
,不必买这本书.
5.Programming The Microsoft Windows Driver Model by Walter Oney(微软出版社)
本书主要讨论WDM的开发.它详细地讨论了WDM drivers的结构以及如何构造它们. 本书深
入清晰地解释了PIO/DMA及其类型drivers的开发.本书"is clear written",它所提供的
信息是精确和可靠的!
结论
如果你拥有Windows NT Device Driver Development(Peter Viscarola and W.Anthony
Mason), Developing Windows NT Devices Drivers(EdwardN.Dekker and Joseph M.N
ewcomer)和 Programming The Microsoft Windows DriverModel(Walter Oney)这三本书
,你就会明白地知道如何写WDM和NT4的drivers了!
三.怎样学习DDK
学DDK的第一步准备功夫是把英文阅读能力练好,你别指望书商会出中译本.因这类书的
卖相太差,比不上VB,Delphi,JAVA这类较大众化的书.再者要找到够格的译者很难.要译好
是要花相当时间,那还到不如去写些轻松的书,稿费也赚得多.
接下来就要练基础工夫,如同张无忌花了6年时间练好九阳真经,等到练乾昆大挪移时只花
数个时辰就OK.要如何练底层基础呢?勤看书,勤coding及Trace别人写得sample code而已
.即使是天才型的Programmer也是要看书,因Window不是他设计的,必须了解Window才有办
法下手.而非像写Algorithm方面的论文般,自己定assumption, Lemma,导出Theme,下con
clusion就完成.所以一些刚入社会的研究生最好先调整自己的心态.
以往我是读一些大师级的书,如:
"Window Programing"的CharlePetzold,
"Undocument Window"系列的Andrew Scullman,
"Win95 system Programming Secrets"的MattPietrek,
"AdvancedWindows"的JefferyRichter.
期刊的话是:
Microsoft System Journal,
Doctor Dobb's Journal,
Window Developer Journal这本期刊是我认为学DDK的人必要订阅的!几乎过个1,2期就会
刊登Window Device Driver相关的文章,而且里面有位Paula女士主持的NT专栏,写的很深
入,不是市面一些标榜NT"大剖析"之类的书籍所能比拟.在Andrew Scrullman的"Undocum
ent NT"尚未问世之前,它是我觉得最有深度的专栏.
接下来就谈与Driver有直接关系的资料:
Device Driver的书籍,我从Win31开始说起:
"Writing Windows Device Driver and VxD",Karen Hazzen,第1,2版是最适合写Win31
Driver的参考书籍.也有一本白皮的"Writing Window Device Driver",我认为它的参考
性很低,因它光抄Win31 DDK Function Description就花了50~60几页,有A钱之嫌.
Win95:
那当然是首推"System Programing for Win95",Walter Oney.
这本巨作.我曾因翻Chapter11~13翻到书页掉落,而重新再买一本.Walter Oney既出,谁与
争锋.有这本就够了!也没有人有胆来挑战他.
WinNT:
唯一的一本:"The NT Device Driver Book",Art Baker.很有系统的一步一步介绍如何写
NT Kernal mode driver.先看这本书然后再看MS的NT DDK on Help会让你较容易了解.当
初没这本书时,我刚开始看DDK Help是看得满头雾水.最好搭配"Inside Windows NT",He
len Custer一起看,因为NT底层已经导入Object Oriented观念(WDM是将NT Kernel mode
driver 加装Plug&Play及Bus handle等新功能),与Win95的Virtual Machine观念相差甚
远.这本书虽是1992年出版,但有对NT的核心运作加以介绍,也是一本难得的好书.
NewGroup and WebSite:
1.Win95是comp.os.ms-windows.programmer.vxd
2.NT的话是comp.os.ms-windows.programmer.nt.kernel-mode
3.Window Device Driver Web site:
http://www.albany.net/~danorton/ddk
http://www.vireo.com
发展工具:
1. 如何要让你日子好过,一定要有套SoftIce for Win95/NT.千万不要用MS的WinDebug,
它根本是无山晓路用.SoftIce可让你用source code level debuging,对有assembly恐惧
症的人是一大福音.(但我还是劝有心学DDK的人还是要摸assembly).
2.VToolsD(for Win31/95),DriverWork(for NT/WDM)
Vireo公司出的DDK Tool让你完全用C来写Driver,我只能说写Driver时,我已经不能没有
它.由其它还免费附Class Library source code,让我Trace的很高兴.
领域知识(Domain Knowledge)
写Driver需了解你要控制的硬件,如Driver有用到DMA/Interrupt,建议你看一下8259,82
37A的资料.在这方面,"微电脑接口技术与应用"是本不错的参考书. Programmer总有一天
会coding不动的时候.但人老成精,只要你的Domain Knowledge够强的话, 还是会有许多
公司请你去当技术经理, 而这也是你能克死年轻力壮Programmer最大的本钱. 多多看些
其他杂志, 接触一些非Programming方面的知识来培养你的Domain Knowledge吧!
四.DDK常用函数列表
Support Function and Data Structure Reference
ASSERT
ASSERTMSG
CM_FULL_RESOURCE_DESCRIPTOR
CM_PARTIAL_RESOURCE_DESCRIPTOR
CM_PARTIAL_RESOURCE_LIST
CM_RESOURCE_LIST
CONFIGURATION_INFORMATION
CONTAINING_RECORD
CONTROLLER_OBJECT
DbgBreakPoint
DbgPrint
DEVICE_DESCRIPTION
DEVICE_OBJECT
DriverEntry
DRIVER_OBJECT
ExAcquireFastMutex
ExAcquireFastMutexUnsafe
ExAcquireResourceExclusiveLite
ExAcquireResourceSharedLite
ExAcquireSharedStarveExclusive
ExAcquireSharedWaitForExclusive
ExAllocateFromNPagedLookasideList
ExAllocateFromPagedLookasideList
ExAllocatePool
ExAllocatePoolWithQuota
ExAllocatePoolWithQuotaTag
ExAllocatePoolWithTag
ExConvertExclusiveToSharedLite
ExDeleteNPagedLookasideList
ExDeletePagedLookasideList
ExDeleteResourceLite
ExFreePool
ExFreeToNPagedLookasideList
ExFreeToPagedLookasideList
ExGetCurrentResourceThread
ExInitializeFastMutex
ExInitializeNPagedLookasideList
ExInitializePagedLookasideList
ExInitializeResourceLite
ExInitializeWorkItem
ExInterlockedInsertHeadList
ExInterlockedInsertTailList
ExInterlockedRemoveHeadList
ExIsResourceAcquiredExclusiveLite
ExIsResourceAcquiredSharedLite
ExQueueWorkItem
ExReleaseFastMutex
ExReleaseFastMutexUnsafe
ExReleaseResourceForThreadLite
ExTryToAcquireFastMutex
ExTryToAcquireResourceExclusiveLite
HalAssignSlotResources
HalGetAdapter
HalGetBusData
HalGetBusDataByOffset
HalGetInterruptVector
HalSetBusData
HalSetBusDataByOffset
HalTranslateBusAddress
HKEY_LOCAL_MACHINE
InitializeListHead
InitializeObjectAttributes
InsertHeadList
InsertTailList
INTERFACE_TYPE
InterlockedDecrement
InterlockedExchange
InterlockedExchangeAdd
InterlockedIncrement
IoAcquireCancelSpinLock
IoAllocateAdapterChannel
IoAllocateController
IoAllocateErrorLogEntry
IoAllocateIrp
IoAllocateMdl
IoAssignResources
IoAttachDevice
IoAttachDeviceToDeviceStack
IoBuildAsynchronousFsdRequest
IoBuildDeviceIoControlRequest
IoBuildPartialMdl
IoBuildSynchronousFSDRequest
IoCallDriver
IoCancelIrp
IoCompleteRequest
IoConnectInterrupt
IoCopyCurrentIrpStackLocationToNext
IoCreateController
IoCreateDevice
IoCreateNotificationEvent
IoCreateSymbolicLink
IoCreateSynchronizationEvent
IoDeleteController
IoDeleteDevice
IoDeleteSymbolicLink
IoDetachDevice
IoDisconnectInterrupt
IO_ERROR_LOG_PACKET
IoFlushAdapterBuffers
IoFreeAdapterChannel
IoFreeController
IoFreeIrp
IoFreeMapRegisters
IoFreeMdl
IoGetConfiguationInformation
IoGetCurrentIrpStackLocation
IoGetCurrentProcess
IoGetDeviceObjectPointer
IoGetNextIrpStackLocation
IoInitializeDpcRequest
IoInitializeIrp
IoInitializeTimer
IoMakeAssociatedIrp
IoMapTransfer
IoMarkIrpPending
IoRegisterShutdownNotification
IoReleaseCancelSpinLock
IoRequestDpc
IO_RESOURCE_DESCRIPTOR
IO_RESOURCE_LIST
IO_RESOURCE_REQUIREMENTS_LIST
IoSetCancelRoutine
IoSetCompletionRoutine
IoSetNextIrpStackLocation
IoSizeOfIrp
IoSkipCurrentIrpStackLocation
IO_STACK_LOCATION
IoStartNextPacket
IoStartNextPacketByKey
IoStartPacket
IoStartTimer
IO_STATUS_BLOCK
IoStopTimer
IoUnregisterShutdownNotification
IoWriteErrorLogEntry
IsListEmpty
IRP
KdPrint
KeAcquireSpinLock
KeAcquireSpinLockAtDpcLevel
KeBugCheck
KeBugCheckEx
KeCancelTimer
KeClearEvent
KeDelayExecutionThread
KeDeregisterBugCheckCallback
KeFlushIoBuffers
KeGetCurrentIrql
KeGetCurrentProcessorNumber
KeGetDcacheFillSize
KeInitializeCallbackRecord
KeInitializeDeviceQueue
KeInitializeDpc
KeInitializeEvent
KeInitializeMutex
KeInitializeSemaphore
KeInitializeSpinLock
KeInitializeTimer
KeInitializeTimerEx
KeInsertByKeyDeviceQueue
KeInsertDeviceQueue
KeInsertQueueDpc
KeLowerIrql
KeNumberProcessors
KeQueryPerformanceCounter
KeQuerySystemTime
KeQueryTickCount
KeQueryTimeIncrement
KeRaiseIrql
KeReadStateEvent
KeReadStateMutex
KeReadStateSemaphore
KeReadStateTimer
KeRegisterBugCheckCallback
KeReleaseMutex
KeReleaseSemaphore
KeReleaseSpinLock
KeReleaseSpinLockFromDpcLevel
KeRemoveByKeyDeviceQueue
KeRemoveDeviceQueue
KeRemoveEntryDeviceQueue
KeRemoveQueueDpc
KeResetEvent
KeSetEvent
KeSetPriorityThread
KeSetTimer
KeSetTimerEx
KeStallExecutionProcessor
KeSynchronizeExecution
KeWaitForMultipleObjects
KeWaitForMutexObject
KeWaitForSingleObject
KEY_BASIC_INFORMATION
KEY_FULL_INFORMATION
KEY_NODE_INFORMATION
KEY_VALUE_BASIC_INFORMATION
KEY_VALUE_FULL_INFORMATION
KEY_VALUE_PARTIAL_INFORMATION
KIRQL
KSYNCHRONIZE_ROUTINE
LARGE_INTEGER
MmAllocateContiguousMemory
MmAllocateNonCachedMemory
MmCreateMdl
MmFreeContiguousMemory
MmFreeNonCachedMemory
MmGetMdlByteCount
MmGetMdlByteOffset
MmGetMdlVirtualAddress
MmGetPhysicalAddress
MmGetSystemAddressForMdl
MmInitializeMdl
MmIsAddressValid
MmMapIoSpace
MmMapLockedPages
MmPrepareMdlForReuse
MmProbeAndLockPages
MmQuerySystemSize
MmSizeOfMdl
MmUnlockPages
MmUnlockPagableImageSection
MmUnmapIoSpace
MmUnmapLockedPages
NTSTATUS
ObDereferenceObject
ObReferenceObjectByHandle
ObReferenceObjectByPointer
PCI_COMMON_CONFIG
PCI_SLOT_NUMBER
PDRIVER_CONTROL
PIO_DPC_ROUTINE
PIO_TIMER_ROUTINE
PKDEFERRED_ROUTINE
PKSTART_ROUTINE
PsCreateSystemThread
PsGetCurrentProcess
PsGetCurrentThread
PsTerminateSystemThread
READ_PORT_BUFFER_type
READ_PORT_type
READ_REGISTER_BUFFER_type
READ_REGISTER_type
RemoveEntryList
RemoveHeadList
RemoveTailList
RtlInitUnicodeString
RtlMoveMemory
RTL_QUERY_REGISTRY_ROUTINE
RTL_QUERY_REGISTRY_TABLE
RtlQueryRegistryValues
RtlUnicodeStringToAnsiString
RtlZeroMemory
UNICODE_STRING
_URB_CONTROL_DESCRIPTOR_REQUEST
_URB_HEADER
UsbBuildGetDescriptorRequest
WRITE_PORT_BUFFER_type
WRITE_PORT_type
WRITE_REGISTER_BUFFER_type
WRITE_REGISTER_type
ZwClose
ZwCreateFile
ZwCreateKey
ZwDeleteKey
ZwEnumerateKey
ZwEnumerateValueKey
ZwFlushKey
ZwMapViewOfSection
ZwOpenKey
ZwOpenSection
ZwQueryKey
ZwQueryValueKey
ZwSetInformationThread
ZwSetValueKey
ZwUnmapViewOfSection