看了近半個月的書,有了一小點的進步。主要是熟悉了一下驅動開發的環境和配置,USB的協議傳輸等等。下面是這段時間的體會。以開發一個簡單的"hello world"為例。 1、先裝VC,然后裝DDK,我裝的是2000DDK,這個順序不要弄反。 2、配置好環境(1)在setting->link->libary modules添加ntoskrnl.lib hal.lib usbd.lib wdm.lib 。可能不需要這么多。(2)在setting->C/C++->category選preprocessor->additional include directories中添加c:/NTDDK/inc,c:/NTDDK/inc/ddk(3)在option中添加合適的lib,include路徑.option->directories選include files添加C:/NTDDK/INC和C:/NTDDK/INC/DDK,在選library files中添加C:/NTDDK/libchk/i386和C:/NTDDK/libfre/i386。整個環境基本上就搭建好了。 3、然后添加代碼。 //1.c #ifdef _cplusplus extern "C" { #endif #include "1.h" #ifdef _cplusplus } #endif
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, ????? IN PUNICODE_STRING RegistryPath) { ?DriverObject->DriverExtension->AddDevice = WDMAddDevice; ?DriverObject->MajorFunction[IRP_MJ_PNP] = WDMPnp; ?return STATUS_SUCCESS; ? }
NTSTATUS WDMAddDevice(IN PDRIVER_OBJECT DriverObject, ?????? IN PDEVICE_OBJECT PhysicalDeviceObject) { ?NTSTATUS status; ?PDEVICE_OBJECT fdo; ?PDEVICE_EXTENSION dx; ?status = IoCreateDevice( ??DriverObject, ??sizeof(DEVICE_EXTENSION), ??NULL, ??FILE_DEVICE_UNKNOWN, ??0, ??FALSE, ??&fdo); ?if(!NT_SUCCESS(status)) ??return status; ?dx = (PDEVICE_EXTENSION)fdo->DeviceExtension; ?dx->fdo=fdo; ?dx->NextStackDevice = IoAttachDeviceToDeviceStack(fdo,PhysicalDeviceObject); ?fdo->Flags |= DO_BUFFERED_IO|DO_POWER_PAGABLE; ?fdo->Flags &= ~DO_DEVICE_INITIALIZING; ?return STATUS_SUCCESS; } NTSTATUS WDMPnp( IN PDEVICE_OBJECT fdo, ????IN PIRP Irp) { ?PDEVICE_EXTENSION dx = (PDEVICE_EXTENSION)fdo->DeviceExtension; ?PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp); ?NTSTATUS status; ?ULONG MinorFunction = IrpStack->MinorFunction; ?IoSkipCurrentIrpStackLocation(Irp); ?status = IoCallDriver(dx->NextStackDevice,Irp); ?if( MinorFunction==IRP_MN_REMOVE_DEVICE) ?{ ??IoSetDeviceInterfaceState(&dx->ifSymLinkName,FALSE); ??RtlFreeUnicodeString(&dx->ifSymLinkName); ??if(dx->NextStackDevice) ???IoDetachDevice(dx->NextStackDevice); ??IoDeleteDevice(fdo); ?} ?return status; } 1.h #ifdef _cplusplus extern "C" { #endif #include "ntddk.h" #ifdef _cplusplus } #endif
typedef struct _DEVICE_EXTENSION { ??? PDEVICE_OBJECT??? fdo; ??? PDEVICE_OBJECT??? NextStackDevice; ??? UNICODE_STRING??? ifSymLinkName; } DEVICE_EXTENSION, *PDEVICE_EXTENSION; NTSTATUS WDMAddDevice(IN PDRIVER_OBJECT DriverObject, ?????? IN PDEVICE_OBJECT PhysicalDeviceObject); NTSTATUS WDMPnp( IN PDEVICE_OBJECT fdo, ????IN PIRP Irp); 4、在文件中添加makefile和source,makefile從其它驅動程序中就可以原封不動的考過來,source需要改一點,我的source是: TARGETNAME=1 TARGETTYPE=DRIVER DRIVERTYPE=WDM TARGETPATH=OBJ INCLUDES=$(BASEDIR)/inc;/ ???????? $(BASEDIR)/inc/ddk;/ TARGETLIBS=$(DDKROOT)/libfre/i386/ntoskrnl.lib/ ?????????? $(DDKROOT)/libfre/i386/hal.lib/ ?????????? $(DDKROOT)/libfre/i386/wdm.lib ????????? SOURCES=1.c/ makefile為(不用改地): # # DO NOT EDIT THIS FILE!!!? Edit ./sources. if you want to add a new source # file to this component.? This file merely indirects to the real make file # that is shared by all the driver components of the Windows NT DDK # !INCLUDE $(NTMAKEENV)/makefile.def 5、編譯,用DDK中的checked(free) build environment來編譯。進入控制臺后執行build -cz,其中如果編譯不通可以用nmake來調試。 6、build完成后,就會生成一個1.sys文件。 7、給設備寫inf文件,即安裝驅動,inf文件可以從其它驅動文件中拷貝過來,做點小改動就可以了。下面是我寫的, [Version] Signature="$Chicago$" Class=Unknown Provider=%THU% [Manufacturer] %THU% = WdmDriver [WdmDriver] %WdmDriver%=WdmDriver.Install, *WdmDriver [DestinationDirs] WdmDriver.Files.Driver=10, System32/Drivers WdmDriver.Files.Driver.NT=10, System32/Drivers [SourceDisksNames] 1="WdmDriver directory",,,obj/i386/ [SourceDisksFiles] 1.sys=1 ;; The Win2K DDK documentation contains an excellent INF reference. ;--------- Version Section --------------------------------------------------- [Version] Signature="$CHICAGO$" Provider=LC_Device DriverVer=8/21/2002,3.0.0.3 ; If device fits one of the standard classes, use the name and GUID here, ; otherwise create your own device class and GUID as this example shows. Class=Unknown ClassGUID={ff646f80-8def-11d2-9449-00105a075f6b} ;--------- SourceDiskNames and SourceDiskFiles Section ----------------------- ; These sections identify source disks and files for installation. They are ; shown here as an example, but commented out. [SourceDisksNames] 1 = "1",Disk1,, [SourceDisksFiles] 1.sys = 1,objfre/i386, ;--------- ClassInstall/ClassInstall32 Section ------------------------------- ; Not necessary if using a standard class ; 9X Style [ClassInstall] Addreg=Class_AddReg ; NT Style [ClassInstall32] Addreg=Class_AddReg [Class_AddReg] HKR,,,,%DeviceClassName% HKR,,Icon,,"-5" ;--------- DestinationDirs Section ------------------------------------------- [DestinationDirs] YouMark_Files_Driver = 10,System32/Drivers ;--------- Manufacturer and Models Sections ---------------------------------- [Manufacturer] %MfgName%=Mfg0 [Mfg0] ; PCI hardware Ids use the form ; PCI/VEN_aaaa&DEV_bbbb&SUBSYS_cccccccc&REV_dd ;改成你自己的ID %DeviceDesc%=YouMark_DDI, PCI/VEN_9999&DEV_9999 ;---------- DDInstall Sections ----------------------------------------------- ; --------- Windows 9X ----------------- ; Experimentation has shown that DDInstall root names greater than 19 characters ; cause problems in Windows 98 [YouMark_DDI] CopyFiles=YouMark_Files_Driver AddReg=YouMark_9X_AddReg [YouMark_9X_AddReg] HKR,,DevLoader,,*ntkern HKR,,NTMPDriver,,HelloWDM.sys HKR, "Parameters", "BreakOnEntry", 0x00010001, 0 ; --------- Windows NT ----------------- [YouMark_DDI.NT] CopyFiles=YouMark_Files_Driver AddReg=YouMark_NT_AddReg [YouMark_DDI.NT.Services] Addservice = HelloWDM, 0x00000002, YouMark_AddService [YouMark_AddService] DisplayName = %SvcDesc% ServiceType = 1 ; SERVICE_KERNEL_DRIVER StartType = 3 ; SERVICE_DEMAND_START ErrorControl = 1 ; SERVICE_ERROR_NORMAL ServiceBinary = %10%/System32/Drivers/1.sys [YouMark_NT_AddReg] HKLM, "System/CurrentControlSet/Services/HelloWDM/Parameters",/ "BreakOnEntry", 0x00010001, 0 ; --------- Files (common) -------------
[YouMark_Files_Driver] 1.sys ;--------- Strings Section --------------------------------------------------- [Strings] ProviderName="Flying L Co.,Ltd." MfgName="LC Soft" DeviceDesc="Hello World WDM!" DeviceClassName="LC_Device" SvcDesc="???" 對inf文件的一點小注釋,:),inf文件是按照部分來劃分的,每個部分用[]來標記。分號;表示注釋,%表示(%文本%)表示一個字符串。 一個最基本的起步,未來還有很多工作要做,繼續努力! |